2011-10-22 161 views
4

--------------------這需要4秒來執行(使用2000 000行)爲什麼?------- --------------SQL Server 2005性能查詢

DECLARE @AccountId INT 
DECLARE @Max INT 
DECLARE @MailingListId INT 

SET @AccountId = 6730 
SET @Max = 2000 
SET @MailingListId = 82924 

SELECT TOP (@Max) anp_Subscriber.Id , Name, Email 
FROM anp_Subscription WITH(NOLOCK) 
    INNER JOIN anp_Subscriber WITH(NOLOCK) 
    ON anp_Subscriber.Id = anp_Subscription.SubscriberId 
WHERE [MailingListId] = @MailingListId 
    AND Name LIKE '%joe%' 
    AND [AccountID] = @AccountId 

---------------------這需要< 1秒執行(與2000年000行)-----------------------

SELECT TOP 2000 anp_Subscriber.Id ,Name, Email 
FROM anp_Subscription WITH(NOLOCK) 
    INNER JOIN anp_Subscriber WITH(NOLOCK) 
    ON anp_Subscriber.Id = anp_Subscription.SubscriberId 
WHERE [MailingListId] = 82924 
    AND Name LIKE '%joe%' 
    AND [AccountID] = 6730 

爲什麼excecution時間差?我想在頂部使用查詢。我可以做任何事情來優化它嗎?

在此先感謝!/Christian

+0

我認爲這是相關的:http://stackoverflow.com/questions/414336/why-does-the-sqlserver-optimizer-get-so-confused-with-parameters –

+0

而MSDN文章:http:// technet.microsoft.com/en-gb/library/cc966425.aspx#E6TAE –

+0

在第一種情況下,SQL Server必須使用這些參數的任何可能值的參數來優化查詢。在第二種情況下,使用實際的字面值,查詢優化器可以選擇更合適的查詢計劃 - 因爲它只需要針對這些特定的值進行完善。 –

回答

0

要檢查的一個可能的項目是表中的MailingListId和AccountId字段的類型是INT。例如,如果類型是BIGINT,查詢優化器通常不會在這些字段上使用索引。當您顯式定義值而不是使用變量時,這些值將隱式轉換爲正確的類型。

確保類型匹配。

6

OPTION (RECOMPILE)添加到查詢的末尾。

SQL Server不會「嗅探」變量的值,因此您將根據猜測的統計信息而不是爲實際變量值量身定製計劃。

+0

謝謝。這有助於提高性能。但另一個問題是:每次執行查詢時,是否要求服務器重新編譯?它可能會被用於非常... –

+0

@ user1008621 - 如果你要不斷重新編譯相同的值,你可以嘗試'OPTION(OPTIMIZE FOR)按照GilM的建議,看起來有點浪費時間。 –

+0

我也這麼認爲,但是在這個查詢中我可以優化的唯一值是@Max,並且出於某種原因,執行時間沒有得到改善,因爲...任何想法爲什麼? –

0

第二個查詢必須處理2000條記錄。點。

第一個必須處理所有記錄以找到最大值。

Top 2000不會讓你成爲最高的2000年,它會以任何順序獲得結果集的第一個2000年。

如果喲uwant改變它們是相同的,第二應改爲

TOP 1

然後爲了通過anp_Subscriber.Id降序(加快第一個選項)。

+0

我沒有使用Max函數。對我來說,使用@Max作爲變量名稱可能並不聰明......:/ –