LIKE इंडेक्स का उपयोग करता है, CHARINDEX नहीं?


22

यह प्रश्न मेरे पुराने प्रश्न से संबंधित है । नीचे दी गई क्वेरी को निष्पादित करने में 10 से 15 सेकंड लग रहे थे:

SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
FROM [company].dbo.[customer]
WHERE (Charindex('123456789',CAST([company].dbo.[customer].[Phone no] AS VARCHAR(MAX)))>0) 

कुछ लेखों में मैंने देखा कि प्रयोग करने CASTऔर CHARINDEXअनुक्रमण से कोई लाभ नहीं होगा। कुछ लेख भी हैं जो कहते हैं कि प्रयोग LIKE '%abc%'करते समय अनुक्रमण से लाभ नहीं LIKE 'abc%'होगा:

http://bytes.com/topic/sql-server/answers/81467-use-charindex-vs-like-where /programming/803783/sql-server-index-any-improvement-for -उत्तर-प्रश्न http://www.sqlservercentral.com/Forums/Topic186262-8-1.aspx#bm186568

मेरे मामले में मैं प्रश्न को फिर से लिख सकता हूं:

SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
FROM [company].dbo.[customer]
WHERE [company].dbo.[customer].[Phone no]  LIKE '%123456789%'

यह क्वेरी पिछले आउटपुट की तरह ही आउटपुट देती है। मैंने कॉलम के लिए एक गैर-सूचीबद्ध सूचकांक बनाया है Phone no। जब मैं इस क्वेरी को निष्पादित करता हूं तो यह केवल 1 सेकंड में चलता है । 14 सेकंड पहले की तुलना में यह एक बहुत बड़ा बदलाव है ।

LIKE '%123456789%'अनुक्रमण से कैसे लाभ होता है?

सूचीबद्ध लेख यह क्यों कहते हैं कि यह प्रदर्शन में सुधार नहीं करेगा?

मैंने उपयोग करने के लिए क्वेरी को फिर से लिखने की कोशिश की CHARINDEX, लेकिन प्रदर्शन अभी भी धीमा है। CHARINDEXइंडेक्सिंग से फायदा क्यों नहीं होता क्योंकि यह LIKEक्वेरी करता है?

क्वेरी का उपयोग करना CHARINDEX:

SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
 FROM [Company].dbo.[customer]
 WHERE ( Charindex('9000413237',[Company].dbo.[customer].[Phone no])>0 ) 

निष्पादन योजना:

यहाँ छवि विवरण दर्ज करें

क्वेरी का उपयोग करना LIKE:

SELECT [customer].[Customer name],[customer].[Sl_No],[customer].[Id]
 FROM [Company].dbo.[customer]
 WHERE[Company].dbo.[customer].[Phone no] LIKE '%9000413237%'

निष्पादन योजना:

LIKE क्वेरी प्लान

जवाबों:


28

इंडेक्सिंग से LIKE '% 123456789%' कैसे लाभान्वित होता है?

केवल एक छोटा सा। क्वेरी प्रोसेसर पूरे टेबल के बजाय मैचों की तलाश में पूरे गैर-अनुक्रमित सूचकांक को स्कैन कर सकता है (क्लस्टर इंडेक्स)। गैर-अनुक्रमित अनुक्रमणिका आम तौर पर उनके द्वारा बनाई गई तालिका से छोटी होती है, इसलिए गैर-अनुक्रमित सूचकांक को स्कैन करना तेज हो सकता है।

नकारात्मक पक्ष यह है कि क्वेरी द्वारा आवश्यक कोई भी स्तंभ जो गैर-अनुक्रमित अनुक्रमणिका परिभाषा में शामिल नहीं हैं, उन्हें आधार तालिका, प्रति पंक्ति में देखा जाना चाहिए।

ऑप्टिमाइज़र तालिका (क्लस्टर इंडेक्स) को स्कैन करने और लागत अनुमानों के आधार पर गैर-सूचीबद्ध इंडेक्स को लुकअप के साथ स्कैन करने के बीच एक निर्णय लेता है। अनुमानित लागत बहुत हद तक इस बात पर निर्भर करती है कि आशावादी आपके द्वारा चुने जाने की कितनी पंक्तियों की उम्मीद करता है LIKEया CHARINDEXभविष्यवाणी करता है।

सूचीबद्ध लेख यह क्यों कहते हैं कि यह प्रदर्शन में सुधार नहीं करेगा?

ऐसी LIKEस्थिति के लिए जो वाइल्डकार्ड से शुरू नहीं होती है , SQL सर्वर पूरी चीज़ को स्कैन करने के बजाय इंडेक्स का आंशिक स्कैन कर सकता है। उदाहरण के लिए, LIKE 'A%केवल सूचकांक रिकॉर्ड >= 'A'और < 'B'(सटीक सीमा मान टकराव पर निर्भर करते हैं) का परीक्षण करके सही मूल्यांकन किया जा सकता है ।

इस प्रकार की क्वेरी बी-ट्री इंडेक्स की मांग करने की क्षमता का उपयोग कर सकती है: हम सीधे >= 'A'बी-ट्री का उपयोग करके पहले रिकॉर्ड पर जा सकते हैं , फिर इंडेक्स कुंजी क्रम में आगे स्कैन कर सकते हैं जब तक कि हम एक रिकॉर्ड तक नहीं पहुंचते जो < 'B'परीक्षण में विफल रहता है । चूंकि हमें LIKEपरीक्षण को कम संख्या में पंक्तियों में लागू करने की आवश्यकता है , इसलिए प्रदर्शन आम तौर पर बेहतर होता है।

इसके विपरीत, LIKE '%Aएक आंशिक स्कैन में नहीं बदला जा सकता है क्योंकि हम नहीं जानते कि कहां से शुरू करें या समाप्त करें; कोई भी रिकॉर्ड समाप्त हो सकता है 'A', इसलिए हम पूरे सूचकांक को स्कैन करने और प्रत्येक पंक्ति का व्यक्तिगत रूप से परीक्षण करने पर सुधार नहीं कर सकते हैं।

मैंने उपयोग करने के लिए क्वेरी को फिर से लिखने की कोशिश की CHARINDEX, लेकिन प्रदर्शन अभी भी धीमा है। CHARINDEXअनुक्रमण से लाभ क्यों नहीं होता क्योंकि यह LIKE क्वेरी करता है?

क्वेरी ऑप्टिमाइज़र के पास टेबल (क्लस्टर इंडेक्स) स्कैन करने और नॉनक्लेस्टेड इंडेक्स (लुकअप के साथ) दोनों मामलों में स्कैन करने के बीच एक ही विकल्प है

लागत अनुमान के आधार पर दोनों के बीच चुनाव किया जाता है । ऐसा होता है कि SQL सर्वर दो तरीकों के लिए एक अलग अनुमान लगा सकता है। LIKEक्वेरी के रूप के लिए, अनुमान विशेष रूप से सटीक अनुमान लगाने के लिए विशेष स्ट्रिंग आंकड़ों का उपयोग करने में सक्षम हो सकता है। CHARINDEX > 0प्रपत्र एक अनुमान के आधार पर एक अनुमान पैदा करता है।

ऑप्टिमाइज़र के लिए क्लस्टर्ड इंडेक्स स्कैन के लिए CHARINDEXऔर लुकअप के साथ नॉन- क्लस्टर किए गए इंडेक्स स्कैन को चुनने के लिए अलग-अलग अनुमान पर्याप्त हैं LIKE। यदि आप CHARINDEXक्वेरी को संकेत के साथ गैर-अनुक्रमित इंडेक्स का उपयोग करने के लिए बाध्य करते हैं , तो आपको उसी योजना को प्राप्त करना होगा LIKE, और प्रदर्शन उसी के बारे में होगा:

SELECT
    [Customer name],
    [Sl_No],
    [Id]
FROM dbo.customer WITH (INDEX (f))
WHERE 
    CHARINDEX('9000413237', [Phone no]) >0;

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

यदि आप LIKE %thing%अक्सर खुद को खोज की जरूरत पाते हैं , तो आप एक ऐसी तकनीक पर विचार करना चाह सकते हैं जिसके बारे में मैंने ट्राइग्राम वाइल्डकार्ड स्ट्रिंग सर्च इन एसक्यूएल सर्वर में लिखा था ।


16

एसक्यूएल सर्वर स्ट्रिंग कॉलम में सबस्ट्रिंग के आंकड़ों को उन प्रयासों के रूप में बनाए रखता है जो LIKEक्वेरी द्वारा उपयोग करने योग्य होते हैं लेकिन द्वारा नहीं CHARINDEX

इसके बारे में अधिक जानने के लिए स्ट्रिंग सारांश सांख्यिकी अनुभाग देखें ।

कुछ महत्वपूर्ण चेतावनी यह है कि वाइल्डकार्ड से बचने का काम ESCAPEकीवर्ड के बजाय मालिकाना वर्ग ब्रैकेटिंग तकनीक से किया जाना चाहिए और यह कि 80 से अधिक वर्णों के लिए केवल पहले और अंतिम 40 अक्षरों का उपयोग किया जाता है।

WHERE ( Charindex('9000413237',[Company].dbo.[customer].[Phone no])>0 ) 

सिर्फ एक असमानता के लिए मानक अनुमान का उपयोग करेगा कि 30% पंक्तियों को वापस किया जाएगा।

LIKEक्वेरी (आपके मामले में) शायद अनुमान बहुत कम पंक्तियां विधेय से मेल खाएगी।

ध्यान दें कि अग्रणी वाइल्डकार्ड अभी भी एक इंडेक्स की तलाश को रोकता है। एक संपूर्ण सूचकांक अभी भी स्कैन किया गया है, लेकिन यह एक अलग का उपयोग करता है जो क्लस्टर इंडेक्स की तुलना में संकीर्ण है। संकरा सूचकांक क्वेरी द्वारा उपयोग किए जाने वाले सभी स्तंभों को कवर नहीं करता है इसलिए दूसरी योजना के लिए लापता कॉलम को पुनः प्राप्त करने के लिए एक महत्वपूर्ण खोज की आवश्यकता होती है।

यह योजना 30% अनुमान के साथ चुने जाने की संभावना नहीं है। SQL सर्वर संपूर्ण क्लस्टर इंडेक्स को स्कैन करना और कई लुकअप से बचने के लिए सस्ता होगा। अतिरिक्त उदाहरणों के लिए टिपिंग बिंदु पर इस लेख को देखें ।


मैं आपके स्पष्टीकरण से स्पष्ट नहीं हूं। क्या आप कह रहे हैं कि लाइकनेक्स की तुलना में इसका उपयोग करना बेहतर है?
आईटी रिसर्चर

3
@ITresearcher - हां, संभावित रूप से, केवल एक कंबल अनुमान का उपयोग करने के बजाय कि यह कितनी पंक्तियों की स्थिति से मेल खाएगा ( 30%) यह LIKEआपूर्ति की गई पैटर्न और स्ट्रिंग सारांश आंकड़ों को देख सकता है और अधिक सटीक अनुमान प्राप्त कर सकता है। इसके साथ सशस्त्र यह एक अलग और अधिक उपयुक्त योजना चुन सकता है।
मार्टिन स्मिथ

3
... या, "सबसे खराब स्थिति" में, वही योजना।
हारून बर्ट्रेंड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.