हम SQL Server 2008 R2 का उपयोग कर रहे हैं, और एक प्राथमिक आईडी इंडेक्स के साथ एक बहुत बड़ी (100M + पंक्तियाँ) तालिका और datetime
एक गैर-अनुक्रमित सूचकांक वाला एक कॉलम है। हम कुछ अत्यधिक असामान्य क्लाइंट / सर्वर व्यवहार को विशेष रूप से अनुक्रमित डेटाइम कॉलम पर एक order by
क्लॉज के उपयोग के आधार पर देख रहे हैं ।
मैं निम्नलिखित पोस्ट के माध्यम से पढ़ता हूं: /programming/1716798/sql-server-2008-ordering-by-datetime-is-too-slow लेकिन क्लाइंट या सर्वर के साथ जो चल रहा है उससे अधिक चल रहा है यहाँ वर्णित करें।
यदि हम निम्नलिखित क्वेरी चलाते हैं (कुछ सामग्री की सुरक्षा के लिए संपादित):
select *
from [big table]
where serial_number = [some number]
order by test_date desc
हर बार क्वेरी आउट-आउट। SQL Server Profiler में निष्पादित क्वेरी सर्वर के लिए इस तरह दिखता है:
exec sp_cursorprepexec @p1 output,@p2 output,NULL,N'select * .....
अब यदि आप क्वेरी को संशोधित करते हैं, तो यह कहें:
declare @temp int;
select * from [big table]
where serial_number = [some number]
order by test_date desc
SQL सर्वर प्रोफाइलर निष्पादित क्वेरी को सर्वर के समान दिखता है, और यह तुरंत काम करता है:
exec sp_prepexec @p1 output, NULL, N'declare @temp int;select * from .....
तथ्य की बात के रूप में, आप एक अप्रयुक्त घोषित बयान के बजाय एक खाली टिप्पणी ('-' ') भी डाल सकते हैं और समान परिणाम प्राप्त कर सकते हैं। इसलिए शुरू में हम इस मुद्दे के मूल कारण के रूप में सपा पूर्व प्रोसेसर की ओर इशारा कर रहे थे, लेकिन अगर आप ऐसा करते हैं:
select *
from [big table]
where serial_number = [some number]
order by Cast(test_date as smalldatetime) desc
यह तुरन्त भी काम करता है (आप इसे किसी अन्य datetime
प्रकार के रूप में भी डाल सकते हैं ), मिलीसेकंड में परिणाम लौटाता है। और प्रोफाइलर सर्वर के अनुरोध को निम्नानुसार दिखाता है:
exec sp_cursorprepexec @p1 output, @p2 output, NULL, N'select * from .....
ताकि sp_cursorprepexec
मुद्दे के पूर्ण कारण से प्रक्रिया को कुछ हद तक बाहर रखा जा सके । इसे इस तथ्य में जोड़ें कि इसे sp_cursorprepexec
'ऑर्डर द्वारा' का उपयोग नहीं किए जाने पर भी कॉल किया जाता है और इसका परिणाम भी तुरंत मिलता है।
हम इस मुद्दे के लिए काफी घूमा करते हैं, और मैं दूसरों से मिलते-जुलते मुद्दों को देखता हूं, लेकिन कोई भी इसे इस स्तर तक नहीं ले जाता है।
तो क्या दूसरों ने इस व्यवहार को देखा है? क्या किसी के पास व्यवहार बदलने के लिए अर्थहीन एसक्यूएल को चुनिंदा कथन के सामने रखने से बेहतर कोई समाधान है? एसक्यूएल सर्वर होने के नाते डेटा एकत्र करने के बाद ऑर्डर को लागू करना चाहिए, यह निश्चित लगता है कि यह सर्वर में एक बग है जो लंबे समय तक कायम है। हमने इस व्यवहार को अपनी कई बड़ी तालिकाओं के अनुरूप पाया है, और प्रतिलिपि प्रस्तुत करने योग्य है।
संपादन:
मुझे एक डाल भी डालनी चाहिए जिससे forceseek
समस्या गायब हो जाए।
मुझे खोजकर्ताओं की मदद करने के लिए जोड़ना चाहिए, ODBC टाइमआउट त्रुटि को फेंक दिया गया है: [Microsoft] [ODBC SQL सर्वर ड्राइवर] ऑपरेशन रद्द
10/12/2012 को जोड़ा गया: फिर भी मूल कारण का शिकार करना, (Microsoft को देने के लिए एक नमूना बनाने के साथ, मैं प्रस्तुत करने के बाद यहां किसी भी परिणाम को पार करूंगा)। मैं कार्यशील क्वेरी (अतिरिक्त टिप्पणी / घोषणा विवरण के साथ) और गैर-कार्यशील क्वेरी के बीच ODBC ट्रेस फ़ाइल में खुदाई कर रहा हूं। मूलभूत ट्रेस अंतर नीचे पोस्ट किया गया है। यह SQLBindCol चर्चाओं के पूरा होने के बाद SQLExtendedFetch कॉल करने के लिए कॉल पर होता है। कॉल रिटर्न कोड -1 के साथ विफल रहता है, और पैरेंट थ्रेड SQLCancel में प्रवेश करता है। चूंकि हम मूल ग्राहक और विरासत ODBC ड्राइवरों दोनों के साथ इसका उत्पादन करने में सक्षम हैं, इसलिए मैं अभी भी सर्वर साइड पर कुछ संगतता समस्या की ओर इशारा कर रहा हूं।
(clip)
MSSQLODBCTester 1664-1718 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)
HSTMT 0x001EEA10
UWORD 16
SWORD 1 <SQL_C_CHAR>
PTR 0x03259030
SQLLEN 51
SQLLEN * 0x0326B820 (0)
MSSQLODBCTester 1664-1718 ENTER SQLExtendedFetch
HSTMT 0x001EEA10
UWORD 1 <SQL_FETCH_NEXT>
SQLLEN 1
SQLULEN * 0x032677C4
UWORD * 0x032679B0
MSSQLODBCTester 1664-1fd0 ENTER SQLCancel
HSTMT 0x001EEA10
MSSQLODBCTester 1664-1718 EXIT SQLExtendedFetch with return code -1 (SQL_ERROR)
HSTMT 0x001EEA10
UWORD 1 <SQL_FETCH_NEXT>
SQLLEN 1
SQLULEN * 0x032677C4
UWORD * 0x032679B0
DIAG [S1008] [Microsoft][ODBC SQL Server Driver]Operation canceled (0)
MSSQLODBCTester 1664-1fd0 EXIT SQLCancel with return code 0 (SQL_SUCCESS)
HSTMT 0x001EEA10
MSSQLODBCTester 1664-1718 ENTER SQLErrorW
HENV 0x001E7238
HDBC 0x001E7B30
HSTMT 0x001EEA10
WCHAR * 0x08BFFC5C
SDWORD * 0x08BFFF08
WCHAR * 0x08BFF85C
SWORD 511
SWORD * 0x08BFFEE6
MSSQLODBCTester 1664-1718 EXIT SQLErrorW with return code 0 (SQL_SUCCESS)
HENV 0x001E7238
HDBC 0x001E7B30
HSTMT 0x001EEA10
WCHAR * 0x08BFFC5C [ 5] "S1008"
SDWORD * 0x08BFFF08 (0)
WCHAR * 0x08BFF85C [ 53] "[Microsoft][ODBC SQL Server Driver]Operation canceled"
SWORD 511
SWORD * 0x08BFFEE6 (53)
MSSQLODBCTester 1664-1718 ENTER SQLErrorW
HENV 0x001E7238
HDBC 0x001E7B30
HSTMT 0x001EEA10
WCHAR * 0x08BFFC5C
SDWORD * 0x08BFFF08
WCHAR * 0x08BFF85C
SWORD 511
SWORD * 0x08BFFEE6
MSSQLODBCTester 1664-1718 EXIT SQLErrorW with return code 100 (SQL_NO_DATA_FOUND)
HENV 0x001E7238
HDBC 0x001E7B30
HSTMT 0x001EEA10
WCHAR * 0x08BFFC5C
SDWORD * 0x08BFFF08
WCHAR * 0x08BFF85C
SWORD 511
SWORD * 0x08BFFEE6
(clip)
Microsoft कनेक्ट केस 10/12/2012 जोड़ा गया:
मुझे यह भी ध्यान देना चाहिए कि हमने कार्यप्रणाली और गैर-कामकाजी प्रश्नों दोनों के लिए क्वेरी योजनाओं को देखा। वे दोनों निष्पादन गणना के आधार पर उचित रूप से उपयोग किए जाते हैं। कैश्ड प्लान को फ्लश करने और री-रन करने से क्वेरी की सफलता में बदलाव नहीं होता है।
sp_executesql
देखें और देखें कि क्या होता है।
select id, test_date from [big table] where serial_number = ..... order by test_date
- मैं सोच रहा हूं कि क्याSELECT *
आपके प्रदर्शन पर नकारात्मक प्रभाव पड़ता है। यदि आपके पास एक गैर-अनुक्रमित सूचकांक हैtest_date
और उस पर एक संकुल सूचकांकid
(यह मानते हुए कि इसे क्या कहा जाता है), इस क्वेरी को उस गैर-अनुक्रमित सूचकांक द्वारा कवर किया जाना चाहिए और इस तरह से बहुत जल्दी वापस आना चाहिए