Сведения о вопросе

Gentleman

07:59, 24th August, 2020

Теги

Почему сервер SQL работает быстрее, когда вы индексируете таблицу после ее заполнения?

Просмотров: 523   Ответов: 9

У меня есть sproc, который помещает 750k записей во временную таблицу через запрос в качестве одного из своих первых действий. Если я создаю индексы для временной таблицы до ее заполнения, то выполнение элемента занимает примерно вдвое больше времени, чем при индексации После заполнения таблицы. (Индекс-это целое число в одном столбце, индексируемая таблица - это всего лишь два столбца, каждый из которых является одним целым числом.)

Это кажется мне немного странным, но тогда у меня нет самого твердого понимания того, что происходит под капотом. У кого-нибудь есть ответ на этот вопрос?



  Сведения об ответе

DO__IT

12:46, 5th August, 2020

Если вы создадите кластеризованный индекс, это повлияет на способ физического упорядочения данных на диске. Лучше добавить индекс постфактум и позволить компоненту database engine переупорядочить строки, когда он знает, как распределяются данные.

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

Именно так обстоит дело с ядром базы данных - если вы дадите ему знать обо всем задании, оно может быть гораздо более эффективным, чем если вы просто передадите ему строку за раз.


  Сведения об ответе

lesha

02:46, 3rd August, 2020

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


  Сведения об ответе

piter

04:41, 8th August, 2020

Вам никогда не следует создавать индекс на пустой таблице, если вы собираетесь массово загружать его сразу после этого. Индексы должны поддерживаться по мере изменения данных в таблице, поэтому представьте, что для каждой вставки в таблице индекс пересчитывается (что является дорогостоящей операцией). Сначала загрузите таблицу и создайте индекс после завершения загрузки. Вот так и происходит разница в производительности.


  Сведения об ответе

screen

04:03, 28th August, 2020

Подумайте об этом так.

Дано
unorderedList = {5, 1,3}
orderedList = {1,3,5}

добавьте 2 к обоим спискам.
unorderedList = {5, 1,3,2}
orderedList = {1,2,3,5}

Как вы думаете, к какому списку проще добавить еще один?

Кстати, заказ вашего ввода перед загрузкой даст вам boost.


  Сведения об ответе

SEEYOU

20:12, 26th August, 2020

После выполнения больших операций по обработке данных часто приходится обновлять базовые индексы. Это можно сделать с помощью инструкции UPDATE STATISTICS [table].

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


  Сведения об ответе

DINO

05:16, 7th August, 2020

В дополнение к накладным расходам на индексацию, выполнение каждого запроса как транзакции является плохой идеей по той же причине. Если вы выполняете фрагменты вставок (скажем, 100) в пределах 1 явной транзакции, вы также должны увидеть увеличение производительности.


  Сведения об ответе

padenie

21:06, 1st October, 2020

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


  Сведения об ответе

repe

03:51, 9th August, 2020

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

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

Для пересчета распределения значений после вставки всех данных следует использовать статистику обновления . После этого никакой разницы в производительности не должно наблюдаться.


  Сведения об ответе

прога

02:39, 4th August, 2020

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

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться