您描述的行爲通常是由於緩存不正確的查詢計劃和/或過期的統計信息。
當你在WHERE子句,尤其是那些形式的一長串大量的參數,它通常發生:
(@parameter1 is NULL OR TableColumn1 = @parameter1)
說,緩存的查詢計劃的到期,和proc被稱爲一個非代表性的一組參數。然後該計劃被緩存用於該數據配置文件。但是,如果程序更常用於一組非常不同的參數,則該計劃可能不合適。這通常被稱爲「參數嗅探」。
有一些方法可以減輕和消除此問題,但它們可能涉及權衡並取決於您的SQL Server版本。看看OPTIMIZE FOR
和OPTIMIZE FOR UNKNOWN
。如果(如果)這個過程不經常被調用,但必須儘可能快地運行,你可以將它標記爲OPTION(RECOMPILE)
,每次調用它時強制重新編譯,但不要爲頻繁調用的過程執行此操作,或者在沒有調查的情況下。
[注:知道哪些Service pack and Cumulative Update (CU)您的SQL Server 2008框有,因爲重新編譯和參數嗅探邏輯在一些版本的工作方式不同]
運行此查詢(由格倫·貝瑞),以確定國家統計:
-- When were Statistics last updated on all indexes?
SELECT o.name, i.name AS [Index Name],
STATS_DATE(i.[object_id], i.index_id) AS [Statistics Date],
s.auto_created, s.no_recompute, s.user_created, st.row_count
FROM sys.objects AS o WITH (NOLOCK)
INNER JOIN sys.indexes AS i WITH (NOLOCK)
ON o.[object_id] = i.[object_id]
INNER JOIN sys.stats AS s WITH (NOLOCK)
ON i.[object_id] = s.[object_id]
AND i.index_id = s.stats_id
INNER JOIN sys.dm_db_partition_stats AS st WITH (NOLOCK)
ON o.[object_id] = st.[object_id]
AND i.[index_id] = st.[index_id]
WHERE o.[type] = 'U'
ORDER BY STATS_DATE(i.[object_id], i.index_id) ASC OPTION (RECOMPILE);
我們可能需要更多信息。它是什麼類型的函數(標量,表值或內聯)?它運行的表格有哪些結構?哪些索引可用,以及您期望它使用哪些索引?它開始表現不好時究竟做了什麼? – 2011-01-29 00:31:28