आप जिस व्यवहार का वर्णन कर रहे हैं वह अक्सर गलत तरीके से कैश की गई क्वेरी योजना और/या पुराने आंकड़ों के कारण होता है।
यह आमतौर पर तब होता है जब आपके पास WHERE क्लॉज में बड़ी संख्या में पैरामीटर होते हैं, विशेष रूप से उन लोगों की एक लंबी सूची जो फॉर्म के होते हैं:
(@parameter1 is NULL OR TableColumn1 = @parameter1)
कहें, कैश की गई क्वेरी योजना समाप्त हो जाती है, और खरीद को पैरामीटर के एक गैर-प्रतिनिधि सेट के साथ बुलाया जाता है। फिर इस डेटा प्रोफ़ाइल के लिए योजना को कैश किया जाता है। लेकिन, यदि खरीद अक्सर बहुत अलग मापदंडों के सेट के साथ आम है, तो योजना उपयुक्त नहीं हो सकती है। इसे अक्सर 'पैरामीटर सूँघने' के रूप में जाना जाता है।
इस समस्या को कम करने और खत्म करने के तरीके हैं लेकिन उनमें ट्रेड-ऑफ शामिल हो सकते हैं और आपके SQL सर्वर संस्करण पर निर्भर हो सकते हैं। देखें OPTIMIZE FOR
और OPTIMIZE FOR UNKNOWN
. IF (और यह एक बड़ा अगर है) खरीद को बार-बार बुलाया जाता है, लेकिन जितनी जल्दी हो सके चलाना चाहिए, आप इसे OPTION(RECOMPILE)
, हर बार बुलाए जाने पर पुन:संकलित करने के लिए मजबूर करने के लिए, लेकिन अक्सर प्रोसेस या जांच के बिना ऐसा न करें।
[नोट:जागरूक रहें कि कौन से सर्विस पैक और संचयी अद्यतन (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);