Использование временных таблиц в SQL Server - PullRequest
5 голосов
/ 15 января 2009

Это немного открытый вопрос, но мне бы очень хотелось услышать мнение людей.

Я редко использую явно объявленные временные таблицы (либо табличные переменные, либо обычные таблицы #tmp), так как я считаю, что это не приводит к более краткому, читаемому и отлаживаемому T-SQL. Я также считаю, что SQL может лучше, чем я, использовать временное хранилище, когда оно требуется (например, когда вы используете производную таблицу в запросе).

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

Это общее мнение или у кого-то есть противоположное мнение?

Ответы [ 6 ]

14 голосов
/ 15 января 2009

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

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

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

Другие причины могут включать извлечение данных из полей XML с использованием CROSS APPLY и запросов xpath. Как правило, гораздо эффективнее извлечь это из временной таблицы, а затем работать с временной таблицей. Они также намного быстрее, чем CTE для некоторых задач, поскольку они материализуют результаты запроса, а не переоценивают запрос.

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

'Code Smell' - преувеличение, но если бы я увидел много простых операций с временными таблицами, мне было бы интересно узнать, что происходит.

5 голосов
/ 15 января 2009

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

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

3 голосов
/ 26 февраля 2011

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

Если, как предложил другой автор, ваша рабочая база данных работает на хорошем оборудовании, а ваша база данных tempdb - нет, попросите вашего администратора баз данных переместить ее. Сам SQL Server довольно часто использует tempdb для обработки ваших запросов, поэтому для tempdb важно иметь высокую производительность.

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

3 голосов
/ 15 января 2009

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

0 голосов
/ 21 ноября 2013

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

Делает эти длинные пакетные процессы более удобочитаемыми (иногда это важнее, чем производительность).

0 голосов
/ 23 января 2009

Я тоже избегаю временных таблиц. Насколько я понимаю, временные таблицы на MS SQL Server всегда находятся в файловой группе базы данных master. Это означает, что, хотя ваши таблицы производственных приложений, скорее всего, установлены на дорогостоящем, высокопроизводительном RAID-массиве, ваши временные таблицы расположены везде, где установлен MS SQL Server, который, скорее всего, находится на диске C: в каталоге Program Files.

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