हम इन प्रश्नों के बीच एक बड़ा अंतर देख रहे हैं।एसक्यूएल क्यों चुनें COUNT (*), MIN (col), MAX (col) तेज़ है तो चयन करें MIN (col), MAX (col)
धीमी क्वेरी
SELECT MIN(col) AS Firstdate, MAX(col) AS Lastdate
FROM table WHERE status = 'OK' AND fk = 4193
टेबल 'तालिका'। स्कैन की संख्या 2, तार्किक 2,458,969 पढ़ता है, शारीरिक पढ़ता 0, पढ़ने के लिए आगे पढ़ता 0, कार्य तार्किक पढ़ता 0, कार्य शारीरिक पढ़ता 0, lob-पढ़ने के लिए आगे पढ़ता 0.
एसक्यूएल सर्वर निष्पादन समय: CPU समय = 1966 एमएस , समय बीत गया = 1 9 55 एमएस।
तेजी से क्वेरी
SELECT count(*), MIN(col) AS Firstdate, MAX(col) AS Lastdate
FROM table WHERE status = 'OK' AND fk = 4193
टेबल 'तालिका'। स्कैन गिनती 1, तार्किक 5803 पढ़ता है, शारीरिक पढ़ता 0, पढ़ने के लिए आगे पढ़ता 0, कार्य तार्किक पढ़ता 0, कार्य शारीरिक पढ़ता 0, lob-पढ़ने के लिए आगे पढ़ता 0.
एसक्यूएल सर्वर निष्पादन समय: CPU समय = 0 एमएस , समय बीत गया = 9 एमएस।
प्रश्न
प्रश्नों के बीच भारी अंतर के बीच प्रदर्शन कारण क्या है?
अद्यतन एक छोटी सी अद्यतन टिप्पणी के रूप में दिए गए प्रश्नों पर आधारित:
निष्पादन या बार-बार निष्पादन के आदेश बुद्धिमान कुछ भी नहीं प्रदर्शन बदल जाता है। कोई अतिरिक्त पैरामीटर उपयोग नहीं किया जाता है और (परीक्षण) डेटाबेस निष्पादन के दौरान कुछ और नहीं कर रहा है।
धीरे क्वेरी
|--Nested Loops(Inner Join)
|--Stream Aggregate(DEFINE:([Expr1003]=MIN([DBTest].[dbo].[table].[startdate])))
| |--Top(TOP EXPRESSION:((1)))
| |--Nested Loops(Inner Join, OUTER REFERENCES:([DBTest].[dbo].[table].[id], [Expr1008]) WITH ORDERED PREFETCH)
| |--Index Scan(OBJECT:([DBTest].[dbo].[table].[startdate]), ORDERED FORWARD)
| |--Clustered Index Seek(OBJECT:([DBTest].[dbo].[table].[PK_table]), SEEK:([DBTest].[dbo].[table].[id]=[DBTest].[dbo].[table].[id]), WHERE:([DBTest].[dbo].[table].[FK]=(5806) AND [DBTest].[dbo].[table].[status]<>'A') LOOKUP ORDERED FORWARD)
|--Stream Aggregate(DEFINE:([Expr1004]=MAX([DBTest].[dbo].[table].[startdate])))
|--Top(TOP EXPRESSION:((1)))
|--Nested Loops(Inner Join, OUTER REFERENCES:([DBTest].[dbo].[table].[id], [Expr1009]) WITH ORDERED PREFETCH)
|--Index Scan(OBJECT:([DBTest].[dbo].[table].[startdate]), ORDERED BACKWARD)
|--Clustered Index Seek(OBJECT:([DBTest].[dbo].[table].[PK_table]), SEEK:([DBTest].[dbo].[table].[id]=[DBTest].[dbo].[table].[id]), WHERE:([DBTest].[dbo].[table].[FK]=(5806) AND [DBTest].[dbo].[table].[status]<>'A') LOOKUP ORDERED FORWARD)
फास्ट क्वेरी
|--Compute Scalar(DEFINE:([Expr1003]=CONVERT_IMPLICIT(int,[Expr1012],0)))
|--Stream Aggregate(DEFINE:([Expr1012]=Count(*), [Expr1004]=MIN([DBTest].[dbo].[table].[startdate]), [Expr1005]=MAX([DBTest].[dbo].[table].[startdate])))
|--Nested Loops(Inner Join, OUTER REFERENCES:([DBTest].[dbo].[table].[id], [Expr1011]) WITH UNORDERED PREFETCH)
|--Index Seek(OBJECT:([DBTest].[dbo].[table].[FK]), SEEK:([DBTest].[dbo].[table].[FK]=(5806)) ORDERED FORWARD)
|--Clustered Index Seek(OBJECT:([DBTest].[dbo].[table].[PK_table]), SEEK:([DBTest].[dbo].[table].[id]=[DBTest].[dbo].[table].[id]), WHERE:([DBTest].[dbo].[table].[status]<'A' OR [DBTest].[dbo].[table].[status]>'A') LOOKUP ORDERED FORWARD)
उत्तर
जवाब से नीचे दिए गए मार्टिन स्मिथ समस्या की व्याख्या करने लगता है। सुपर लघु संस्करण यह है कि एमएस-एसक्यूएल क्वेरी-विश्लेषक धीमी क्वेरी में एक क्वेरी प्लान का गलत उपयोग करता है जो एक पूर्ण तालिका स्कैन का कारण बनता है।
एक गणना (*) जोड़ना, प्रारंभिक संकेत (फोरसेकैन) या स्टार्टडेट पर एक संयुक्त सूचकांक, एफके और स्टेटस कॉलम प्रदर्शन समस्या को हल करता है।
यदि आप दूसरी क्वेरी के बाद पहली क्वेरी चलाते हैं तो क्या होगा? – gbn
शायद क्योंकि जब आप गिनती (*) का उपयोग कर रहे हैं तो आप fk = 4193 के लिए प्रत्येक रिकॉर्ड की जांच नहीं करते? – nosbor
क्या आप इन्हें दूसरे के बाद चला रहे हैं? यदि हां: तो क्या होगा यदि आप दोनों प्रश्नों से पहले 'डीबीसीसी ड्रॉप्लेनबफर' और 'डीबीसीसी फ्रीप्रोकैच 'डाल दें? क्या होता है यदि आप अनुक्रम बदलते हैं - पहले तेज क्वेरी चलाएं, फिर धीमी गति से? –