Влияние индекса на операторы обновления, где столбец обновления отсутствует в индексе

16

Я постоянно вижу, как люди говорят, что индексы замедляются update, deleteи insert. Это используется как общее утверждение, как если бы оно было абсолютным.

Настраивая свою базу данных для повышения производительности, я продолжаю сталкиваться с этой ситуацией, которая, кажется, логически противоречит этому правилу для меня, и нигде я не могу найти, чтобы кто-то сказал или объяснил каким-либо иным способом.

В SQL Server, и я полагаю / предполагаю большинство других СУБД, ваши индексы создаются на основе определенных вами столбцов. Вставки и удаления всегда будут влиять на всю строку, поэтому они никак не повлияют на индекс, но обновления кажутся немного более уникальными, они могут затрагивать только определенные столбцы.

Если у меня есть столбцы, которые не включены ни в один индекс, и я обновляю их, они замедляются только потому, что у меня есть индекс для других столбцов в этой таблице?

Например, скажем, в моей Userтаблице у меня есть один или два индекса, первичный ключ, который является столбцом Identity / Auto Increment, и, возможно, другой в некотором столбце внешнего ключа.
Если я обновлю столбец без индекса непосредственно по нему, как, например, по номеру телефона или адресу, замедлится ли это обновление, потому что у меня есть индексы по этой таблице для других столбцов в любой ситуации? Столбцы, которые я обновляю, не находятся в индексах, поэтому, логически, индексы не должны обновляться, не так ли? Во всяком случае, я думаю, что они ускоряются, если я использую индексы в предложении WHERE.

Райан
источник
so there is no way they will not affect the indexкроме отфильтрованных индексов ...
usr
Я считаю, что непокрытый некластеризованный индекс содержит указатели на записи (обычно в конечных узлах кластерного индекса таблицы). Я думаю, что одной из причин, вызывающих замедление во время UPDATE (не включенного атрибута), может быть ситуация, когда UPDATE вызывает перемещение записи в кластеризованном индексе. Я все еще не уверен, приведет ли движение к изменению указателя, ИЛИ, если указатель является просто значением KEY в кластеризованном индексе, в этом случае возможное обновление местоположения не будет иметь значения, потому что система просто выполнит поиск KEY чтобы получить значение записи.
Jmoney38

Ответы:

6

Вы правы, что обновление неиндексированного столбца не приведет к изменениям индексов. В простом случае не будет никакого общего воздействия на стол.

Если запрос может использовать индекс для поиска данных, он может ускорить поиск, но точное поведение (в зависимости от вашего бренда SQL) может отличаться от других брендов SQL. (Я использую Microsoft SQL Server в основном.)

Конечно, обновление столбца со значительно большим объемом данных может привести к некоторому перемещению строк на разные страницы и так далее.

ДКП
источник
1
SQL Server упоминается в OP, я добавил тег, поэтому я думаю, что вы можете предположить, что SQL Server
Том V - Team Monica
10

Для относительно быстрой современной системы добавление одного индекса в таблицу OLTP, вероятно, будет практически невозможно обнаружить с точки зрения производительности для подавляющего большинства систем . Тем не менее, вы не должны создавать ненужные индексы, и вам, вероятно, не следует создавать индексы из одного столбца для каждого столбца в таблице.

Вы правы в предположении, что для многих запросов наличие полезных индексов приведет к очень заметному повышению скорости.

Хотя ваш вопрос связан с производительностью, существует несколько других потенциальных проблем, связанных с добавлением индексов, в том числе:

  1. Время, необходимое для создания индекса, может привести к блокировке при добавлении индекса в таблицу. Замок очень недолговечен и, скорее всего, не создаст большой проблемы.

  2. Изменения индекса приводят к тому, что планы выполнения становятся недействительными для любых планов, которые ссылаются на базовую таблицу. Когда эти планы выполнения перекомпилированы, производительность может ухудшиться для некоторых запросов.

  3. Модификации индекса могут привести к тому, что запросы будут возвращать ошибки, если они не были возвращены ранее. Возьмем случай фильтрованного индекса, который использовался для возврата дат, содержащихся в поле varchar; если фильтр исключил строки, которые не были датами, и этот фильтр впоследствии был изменен, запросы, основанные на этом индексе, теперь могут завершаться неудачно при попытке преобразовать данные, не относящиеся к дате.

  4. Новый индекс может привести к изменению порядка выполнения, в результате чего возможны взаимоблокировки, если не было ранее.

Макс Вернон
источник
«Путь к коду, необходимый для обновления, когда индекс не будет затронут, все еще нуждается в оценке», это не так. Фаза компиляции / оптимизации будет очень хорошо знать, какие индексы необходимо обновить, если таковые имеются, и соответственно создаст план. Оператор UPDATE, который не изменяет (объявляет в списке SET) столбцы в индексе (включая столбцы INCLUDE и кластеризованный ключ), не должен обновлять этот индекс, и фаза выполнения даже не затронет его. DELETE и INSERT, очевидно, затрагивают все столбцы (логически) и должны обновить все индексы.
Ремус Русану
@RemusRusanu, но не нужно ли его оценивать, если индекс можно использовать для поиска строк, которые нужно обновить?
Том V - Команда Моника
@RemusRusanu - Полагаю, что после того, как QO скомпилирует план, больше не требуется CPU; однако, чтобы составить план, он, безусловно, должен это сделать. Если планы составляются часто, это может иметь очень небольшое значение.
Макс Вернон
@TomV использование индекса для поиска строк / кандидатов на удаление / обновление - это совершенно другая тема. Если это так, то преимущества поиска строк с помощью индекса должны подавлять любые проблемы с затратами на обслуживание индекса.
Ремус Русану
@MaxVernon Я бы сказал, что не существует действительного сценария частых перекомпиляций DML (ОБНОВЛЕНИЕ). Я покупаю некоторые случаи для действительных (неизбежных?) Перекомпиляций для специальных запросов. Но ДМЛ? Какое приложение может создавать специальные уникальные операторы UPDATE? Частые перекомпиляции с DML выкрикивают вслух «Parameterize me».
Ремус Русану
-2

Если операция обновления нацелена на неиндексированный столбец фиксированного размера (например, целое число), то, вообще говоря, он не должен быть медленным, но по сравнению с оператором select, обновление в конечном итоге должно быть также записано на медленном диске.

Сорин
источник