Обычно я использую производную таблицу (или CTE , которая иногда является лучшей альтернативой производным запросам в SQL 2005/2008), чтобы упростить чтение и построение запросов, или в случаях, когда SQL не ' Я не могу сделать определенную операцию.
Например, одна из вещей, которую вы не можете сделать без производной таблицы или CTE, - поместить агрегатную функцию в предложение WHERE. Это не сработает:
SELECT name, city, joindate
FROM members
INNER JOIN cities ON cities.cityid = derived.cityid
WHERE ROW_NUMBER() OVER (PARTITION BY cityid ORDER BY joindate) = 1
Но это будет работать:
SELECT name, city, joindate
FROM
(
SELECT name,
cityid,
joindate,
ROW_NUMBER() OVER (PARTITION BY cityid ORDER BY joindate) AS rownum
FROM members
) derived INNER JOIN cities ON cities.cityid = derived.cityid
WHERE rn = 1
Продвинутые предостережения, особенно для крупномасштабной аналитики
Если вы работаете с относительно небольшими наборами данных (не гигабайтами), вы, вероятно, можете прекратить чтение здесь. Если вы работаете с гигабайтами или терабайтами данных и используете производные таблицы, читайте дальше ...
Для очень крупномасштабных операций с данными иногда предпочтительнее создать временную таблицу, чем использовать производный запрос. Это может произойти, если статистика SQL предполагает, что ваш производный запрос вернет намного больше строк, чем запрос на самом деле, что происходит чаще, чем вы думаете. Запросы, в которых ваш основной запрос сам объединяется с нерекурсивным CTE , также проблематичны.
Также возможно, что производные таблицы будут генерировать неожиданные планы запросов. Например, даже если вы поместите строгое предложение WHERE в производную таблицу, чтобы сделать этот запрос очень избирательным, SQL Server может изменить порядок вашего плана запросов, чтобы ваше предложение WHERE оценивалось в плане запросов. См. отзыв Microsoft Connect для обсуждения этой проблемы и обходного пути.
Таким образом, для запросов с высокой производительностью (особенно запросов к хранилищу данных для таблиц объемом более 100 ГБ) я всегда хотел бы создать прототип решения для временных таблиц, чтобы увидеть, получаете ли вы лучшую производительность, чем у производной таблицы или CTE. Это кажется нелогичным, поскольку вы делаете больше операций ввода-вывода, чем идеальное решение с одним запросом, но с временными таблицами вы получаете полный контроль над используемым планом запроса и порядком оценки каждого подзапроса. Иногда это может увеличить производительность в 10 раз и более.
Я также склоняюсь к тому, чтобы использовать временные таблицы в тех случаях, когда мне приходится использовать подсказки запросов, чтобы заставить SQL делать то, что я хочу - если оптимизатор SQL уже «плохо себя ведет», временные таблицы часто являются более ясным способом заставить их действовать так, как вы хотите.
Я не утверждаю, что это распространенный случай - большую часть времени решение для временных таблиц будет, по крайней мере, немного хуже, и иногда подсказки к запросу являются единственным выходом. Но не думайте, что CTE или решение на основе производных запросов также будет вашим самым быстрым вариантом. Тест, тест, тест!