2011-01-20 3 views
6

Может ли кто-нибудь помочь мне понять план выполнения SQL Server для следующих запросов?SQL Server скалярная функция против анализа плана выполнения подзапроса

Я ожидал, что версия подзапроса (Query 2) будет выполняться быстрее, потому что она основана на наборе. Это, кажется, тот случай, когда стереосистеме и обновите запросы самостоятельно - незначительно - однако план выполнения показывает затраты запроса в 15% против 85% соответственно:

//-- Query 1 (15%) - Scalar Function 
SELECT 
    gi.GalleryImageId, 
    gi.FbUserId, 
    dbo.GetGalleryImageVotesByGalleryImageId(gi.GalleryImageId) AS Votes 
FROM 
    GalleryImage gi 

//-- Query 2 (85%) - Subquery 
SELECT 
    gi.GalleryImageId, 
    gi.FbUserId, 
    (SELECT COUNT(*) FROM GalleryImageVote WHERE GalleryImageId = gi.GalleryImageId) 
FROM 
    GalleryImage gi 

Что я здесь отсутствует; ли план выполнения пропускает стоимость функции? Кроме того, какие-либо предложения относительно того, лучше ли обслуживать любой из вышеперечисленных вопросов с запросом CTE или OVER/PARTITION?

Спасибо заранее!

+0

У вас есть они оба в том же окне редактора запросов? Поскольку анализатор запросов будет сравнивать их и присваивать каждому относительное значение тому, что находится в окне (15%/85%). – JNK

+0

Да, вот откуда взялись значения% :) – Robarondaz

+0

Время выполнения запроса не всегда равно стоимости. Кажется, что SQL Server увеличивает загрузку процессора и памяти выше, чем на жестком диске. – jahu

ответ

6

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

set statistics io on 
set statistics time on 

..и сравнивают фактические казни. Статистика может сказать, что ожидание составляет 15%/85%, но фактические данные покажут вам, что на самом деле означает.

Нет никакой серебряной пули для настройки производительности. Даже «лучшие» запросы могут со временем меняться по мере изменения формы или распределения ваших данных.

CTE не будет сильно отличаться, и я не уверен, как вы планируете делать запрос PARTITION по этому вопросу, но можете попробовать форму left join.

SELECT 
    gi.GalleryImageId, 
    gi.FbUserId, 
    count(v.GalleryImageId) AS Votes 
FROM 
    GalleryImage gi 
    LEFT JOIN GalleryImageVote v ON v.GalleryImageId = gi.GalleryImageId 
GROUP BY 
    gi.GalleryImageId, gi.FbUserId 
+0

Привет, я не знал о статистике. Фактическое время выполнения - 265 мс (запрос 1) против 2 мс (запрос 2); намного больше в соответствии с тем, что я изначально ожидал! – Robarondaz

4

Оптимизатор не знает стоимости функции.

Вы может увидеть процессор и читает и продолжительность с помощью профилировщика хотя

Некоторых связанных ответов от подобных вопросов. OneTwo

  • табличных функции Инлайн расшириться в основной запрос (они являются макросами как вид)
  • Скалярных (ваша один) и мульти функция оператора таблицы не делает и черные ящики на «внешний» запрос
+0

Спасибо за помощь! – Robarondaz

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