2010-05-13 2 views
5

Мы пытаемся оптимизировать некоторые из наших запросов.Зачем использовать временную таблицу быстрее, чем вложенный запрос?

Один запроса, выполнив следующие действия:

SELECT t.TaskID, t.Name as Task, '' as Tracker, t.ClientID, (<complex subquery>) Date, 
INTO [#Gadget] 
FROM task t 

SELECT TOP 500 TaskID, Task, Tracker, ClientID, dbo.GetClientDisplayName(ClientID) as Client 
FROM [#Gadget] 
order by CASE WHEN Date IS NULL THEN 1 ELSE 0 END , Date ASC 

DROP TABLE [#Gadget] 

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

Я думал было бы гораздо эффективнее объединить это вниз в одном запросе с помощью подзапросов как:

SELECT TOP 500 TaskID, Task, Tracker, ClientID, dbo.GetClientDisplayName(ClientID) 
FROM 
(
    SELECT t.TaskID, t.Name as Task, '' as Tracker, t.ClientID, (<complex subquery>) Date, 
    FROM task t 
) as sub  
order by CASE WHEN Date IS NULL THEN 1 ELSE 0 END , Date ASC 

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

Но, оказывается, он намного медленнее. 8 секунд против менее 5 секунд.

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

Что мне не хватает?

Редактировать -

Из того, что я был в состоянии видеть из планов запросов, и в значительной степени идентичны, за исключением временной таблицы, которая имеет дополнительную операцию «Таблица Вставка» со стоимостью 18, за исключением %.

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

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

+2

Вы сравнили планы запросов? – Oded

+0

@Однако, см. Мое редактирование. –

+0

Вы очистили кеш данных между каждым тестом? Если нет, это может исказить ваше сравнение. – AdaTheDev

ответ

3

Очевидно, что SQL Server выбирает неправильный план запроса. Да, это может случиться, у меня был тот же сценарий, что и вы несколько раз.

Проблема заключается в том, что оптимизация запроса (вы называете «сложным подзапросом») является нетривиальной задачей: если у вас есть n таблиц, то существует примерно n! возможно присоединиться заказы - и это только начало. Таким образом, вполне правдоподобно, что (а) сначала ваш внутренний запрос и (б), то ваш внешний запрос - хороший способ, но SQL Server не может вывести эту информацию в разумные сроки.

Что вы можете сделать, это help SQL Server. Как пишет Дэн Буш в своей великой книге «SQL Tuning», ключ, как правило, является порядком соединения, исходящим от наиболее избирательной к минимально избирательной таблице.Используя здравый смысл (или метод, описанный в его книге, что намного лучше), вы можете определить, какой порядок соединения будет наиболее уместным, а затем использовать подсказку запроса FORCE ORDER.

В любом случае, каждый запрос уникален, для ускорения работы SQL Server нет «волшебной кнопки». Если вы действительно хотите узнать, что происходит, вам нужно посмотреть (или показать нам) планы запросов ваших запросов. Другие интересные данные показаны SET STATISTICS IO, которые расскажут вам, сколько (дорогого) доступа к жесткому диску вы получаете.

4

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

Конечно, я также видел временные таблицы, делающие вещи медленнее, иногда намного медленнее.

Невозможно заменить профилирование и изучение планов запросов (хотя, с их оценкой, с зерном соли).

0

Я вновь подтвердил этот вопрос здесь: How can I force a subquery to perform as well as a #temp table?

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

+0

Просто обновить. Мартин Смит дал ответ, который работал для меня, указав здесь: http://connect.microsoft.com/SQLServer/feedback/details/218968/ Скорее всего, это устранило проблему этого айзера, хотя Мартин указал, что катушка не есть статистика, подобная темп-таблицам, и это хак, который требует ORDER BY, который может повлечь за собой настоящую стоимость. – Adamantish

Смежные вопросы