#sql #sql-server #performance #database-performance
#sql #sql-сервер #Производительность #база данных-производительность
Вопрос:
Мне интересно, является ли использование табличной переменной более или менее производительным, чем использование примера внутреннего соединения (select)
:
DECLARE @tab TABLE(Id int)
INSERT INTO @tab
SELECT Id
FROM SomeTable
WHERE SomeDate = "10 DAYS AGO"
SELECT *
FROM SomeOtherTable
INNER JOIN @tab t
ON SomeOtherTable.id = t.id
--VERSUS--
SELECT *
FROM SomeOtherTable
INNER JOIN (SELECT Id FROM SomeTable WHERE SomeDate = "10 DAYS AGO") t
ON SomeOtherTable.id = t.id
Для больших запросов первый вариант более удобен в обслуживании, если вам приходится выполнять одно и то же соединение несколько раз, но какой из них наиболее эффективен?
Приветствия
Комментарии:
1. Как насчет
SELECT * FROM SomeOtherTable WHERE Id IN (SELECT Id FROM SomeTable WHERE SomeDate = "10 DAYS AGO")
индексацииSomeDate
и включенияId
?2. проверьте с помощью mysql объясните , если я не ошибаюсь, в общем, вам нужен трюк, чтобы сначала выполнить внутреннее (selct from), вроде как изнутри. Также Google для оптимизации запросов sql или оптимизации соединений sql
3. Я предположил, что SQL Server, пожалуйста, дайте мне знать, правильно ли это.
4. @MartinSmith: совершенно верно, извините, что не упомянул. все: у меня нет прав на создание индексов, и при этом не существует определенного ATM. (Использование SCSM DWDataMart для тех, кто это знает). Профессионал, с которым я время от времени сталкиваюсь, не рекомендовал использовать таблицу #temp.
5. @user972706 — Вам нужно будет протестировать для вашего конкретного случая. Также не могли бы вы подробнее рассказать о «сделать одно и то же соединение несколько раз», я имел в виду ситуацию с несколькими операторами. Если это один оператор, пожалуйста, укажите тип запроса, а также проверьте, действительно ли в плане показано, что он оценивается несколько раз.
Ответ №1:
SQL Server не поддерживает подробную статистику для табличных переменных и не выполняет автоматическую перекомпиляцию для отражения менее детализированных изменений информации о мощности (без TF 2453), поэтому обычно предполагается, что они выводят одну строку.
Это означает, что иногда вы получаете неоптимальную стратегию объединения. Вторая версия может использовать статистику, а также позволяет избежать накладных расходов на вставку промежуточных результатов во временный объект.
Однако, если второй запрос требует больших затрат для оценки, поскольку SomeDate
он не проиндексирован, вы можете повысить производительность, выполнив это заранее (по сравнению с многократной переоценкой).
Вы также можете рассмотреть возможность использования #temp
таблицы, поскольку это позволяет избежать проблемы со статистикой. Некоторые люди предлагают никогда не использовать переменную таблицы в объединениях