2013-04-06 9 views
5

हमारे पास कई "खोज संग्रहित प्रक्रियाएं" हैं जो विभिन्न तालिकाओं में डेटा की पंक्तियों को खोजने के लिए कई निरर्थक पैरामीटर लेती हैं। वे आम तौर पर इस तरह का निर्माण कर रहे हैं:टी-एसक्यूएल - गैर इष्टतम योजना का उपयोग किया जाता है - WHERE क्लॉज शॉर्टरक्यूइट किया जाना चाहिए

SELECT  * 
FROM  Table1 T1 
INNER JOIN Table2 T2 
    ON  T2.something = T1.something 
WHERE  (@parameter1 IS NULL OR T1.Column1 = @parameter1) 
     AND (@parameter2 IS NULL OR T2.Column2 = @parameter2) 
     AND (@parameter3 IS NULL OR T1.Column3 LIKE '%' + @parameter3 + '%') 
     AND (@parameter4 IS NULL OR T2.Column4 LIKE '%' + @parameter4 + '%')  
     AND (@parameter5 IS NULL OR T1.Column5 = @parameter5) 

यह अप करने के लिए 30-40 मापदंडों के लिए पर जा सकते हैं और क्या हमने देखा है कि भले ही parameter1 प्रदान की जाती है, कार्य योजना लागू करके अन्य के सूचकांक स्कैन के माध्यम से चला जाता है सारणी जो क्वेरी को धीमा कर सकती हैं (कुछ सेकंड)। टेस्ट हमें दिखाते हैं कि WHERE कथन से केवल पहली पंक्ति को रखते हुए क्वेरी तुरंत होती है।

  1. मैं पढ़ा है कि shortcuiting संभव नहीं है, लेकिन वहाँ के आसपास काम या प्रश्नों कि संभवतः अधिक कुशल हो जाएगा का निर्माण करने के तरीके हैं?

  2. हम वर्तमान में चयन ही के विभिन्न संस्करणों के होने से इस समस्या को हल/से/कार्यभार संभाला लेकिन मानकों के विभिन्न सेट के साथ कहां खंड में और पर निर्भर करते हुए मापदंडों पारित कर रहे हैं हम के माध्यम से जाने के लिए उचित चयन बयान चुनें। यह लंबे, गन्दा और बनाए रखने के लिए मुश्किल है।

+3

क्या आपने [गतिशील एसक्यूएल] (http://www.sommarskog.se/dynamic_sql.html) का उपयोग करने पर विचार किया है? यहां तक ​​कि [एसक्यूएल इंजेक्शन] (http://en.wikipedia.org/wiki/SQL_injection) के साथ भी यह आपकी आवश्यकताओं के लिए अधिक उपयुक्त हो सकता है। – Oded

+0

पैरामीटरकृत गतिशील एसक्यूएल और एसक्यूएल इंजेक्शन बनाना कोई समस्या नहीं है – StrayCatDBA

+0

मैं गतिशील एसक्यूएल पर एक बार फिर से देखूंगा, लेकिन ऐसा लगता है कि हम चीजों को कैसे करते थे और एसक्यूएल कोड के जटिल तारों को स्वयं अनुप्रयोगों के साथ बनाते थे ऐसी परिस्थितियों का समूह जो त्वरित नज़र में क्वेरी को समझना लगभग असंभव बना देता है। उन प्रश्नों के लिए एसक्यूएल प्रबंधन स्टूडियो के भीतर वाक्यविन्यास हाइलाइटिंग/टूल्स रखने का कोई तरीका भी है? – FrancoisCN

उत्तर

4

SQL सर्वर में क्वेरी योजना संकलित और पुन: उपयोग के लिए संग्रहीत है। भले ही SQL सर्वर देखता है कि आपके पैरामीटर null हैं, इसे एक क्वेरी प्लान के साथ आना होगा जो उन मामलों के लिए काम करेगा जहां वे not null हैं।

क्वेरी संकेत option (recompile) SQL सर्वर 2005 में पेश किया गया था, लेकिन यह SQL Server 2008 तक नहीं था जब यह वास्तव में आपके यहां मौजूद क्वेरी पर प्रभाव डालता था।

जब क्वेरी को फिर से संकलित किया जाता है तो यह क्वेरी प्लान कैश में संग्रहीत नहीं किया जाएगा, इसलिए SQL सर्वर null पैरामीटर के विरुद्ध चेक को अनुकूलित करने के लिए स्वतंत्र है।

इसके बारे में अधिक यहाँ Dynamic Search Conditions in T-SQL

कुछ नमूना कोड आप क्वेरी योजनाओं में अंतर को देखने के लिए पर परीक्षण कर सकते हैं पढ़ें। एसपी को पहला कॉल इंडेक्स की तलाश करेगा और दूसरा क्लस्टर्ड इंडेक्स स्कैन करेगा।

create table T 
(
    ID int identity primary key, 
    Col1 int, 
    Col2 int 
); 

go 

create index IX_T on T(Col1); 

go 

create procedure GetT 
    @Col1 int, 
    @Col2 int 
as 

select ID 
from T 
where (Col1 = @Col1 or @Col1 is null) and 
     (Col2 = @Col2 or @Col2 is null) 
option (recompile); 

go 

exec GetT 1, null 
exec GetT 1, 1 
+1

मैंने इस दृष्टिकोण का उपयोग बड़ी सफलता के लिए किया है। मेरे पास केवल एक ही मुद्दे हैं जब संकलन की संख्या एक मुद्दा बन जाती है। उसके बाद, गतिशील पैरामीटरयुक्त एसक्यूएल एकमात्र वास्तविक विकल्प है। – StrayCatDBA

+0

संकलन की संख्या से कोई समस्या बनने का क्या मतलब है? – FrancoisCN

+0

@FrancoisCN क्वेरी को संकलित करना सर्वर पर संसाधन (सीपीयू) लेता है और 'विकल्प (recompile)' का उपयोग करने का अर्थ है कि क्वेरी प्रत्येक निष्पादन के लिए संकलित की जाएगी। तो इसका उपयोग करने से आपके सर्वर पर तनाव हो सकता है। प्रभाव कितना बड़ा है, इस सवाल की जटिलता और कितनी बार इसे निष्पादित किया जाता है। –

संबंधित मुद्दे