Индексирование одноразовой временной таблицы - PullRequest
0 голосов
/ 28 июня 2018

Коллега работает в бизнесе, который использует Microsoft SQL Server. Их команда создает хранимые процедуры, которые выполняются ежедневно для создания экстрактов данных. Базовые таблицы огромны (некоторые имеют миллиарды строк), поэтому большинство хранимых процедур спроектированы так, что сначала они извлекают только соответствующие строки этих огромных таблиц во временные таблицы, а затем временные таблицы объединяются друг с другом и с другими меньшими по размеру. таблицы для создания окончательной выписки. Нечто похожее на это:

SELECT COL1, COL2, COL3
INTO #TABLE1
FROM HUGETABLE1
WHERE COL4 IN ('foo', 'bar');

SELECT COL1, COL102, COL103
INTO #TABLE2
FROM HUGETABLE2
WHERE COL14 = 'blah';

SELECT COL1, COL103, COL306
FROM #TABLE1 AS T1
JOIN #TABLE2 AS T2
ON T1.COL1 = T2.COL1
LEFT JOIN SMALLTABLE AS ST
ON T1.COL3 = ST.COL3
ORDER BY T1.COL1;

Как правило, временные таблицы не изменяются после их создания (поэтому никаких последующих операций ALTER, UPDATE или INSERT). Для целей этого обсуждения давайте предположим, что временные таблицы используются только один раз позже (поэтому на них будет полагаться только один запрос SELECT).

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

Мой коллега считает, что создание индекса ускорит операции объединения и сортировки. Я полагаю, однако, что общее время будет больше, потому что создание индекса требует времени. Другими словами, я предполагаю, что за исключением крайних случаев (таких как временная таблица, которая сама по себе очень велика или конечный запрос SELECT очень сложен), SQL Server будет использовать статистику, имеющуюся во временных таблицах, для оптимизации окончательного запроса, и при этом он будет эффективно индексировать временные таблицы так, как считает нужным.

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

Никто из нас не знает достаточно об оптимизаторе SQL Server, чтобы понять, в чем мы правы или нет. Не могли бы вы помочь нам лучше понять, какие из наших предположений ближе к истине?

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

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

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

Создание индекса после загрузки данных во временную таблицу. Это устранит фрагментацию и статистика будет создана.

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

Пример ниже запроса до и после сравнения создания индекса во временной таблице:

/* Create index after data load into temp table -- stats is created */
CREATE TABLE #temp ( [text] varchar(50), [num] int);
INSERT INTO #temp([text], [num]) VALUES ('aaa', 1), ('bbb', 2) , ('ccc',3);
CREATE UNIQUE CLUSTERED INDEX [IX_num] ON #temp (num);
DBCC SHOW_STATISTICS ('tempdb..#temp', 'IX_num');

/* Create index before data load into temp table -- stats is not created */
CREATE TABLE #temp_nostats ( [text] varchar(50), [num] int);
CREATE UNIQUE CLUSTERED INDEX [IX_num] ON #temp_nostats (num);
INSERT INTO #temp_nostats([text], [num]) VALUES ('aaa', 1), ('bbb', 2) , ('ccc',3);
DBCC SHOW_STATISTICS ('tempdb..#temp_nostats', 'IX_num');

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

0 голосов
/ 28 июня 2018

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...