SQL 'जैसे' बनाम '=' प्रदर्शन


82

यह सवाल मुझे क्या सोच रहा है के चारों ओर स्कर्ट है, लेकिन जवाब बिल्कुल इसे संबोधित नहीं करते हैं।

ऐसा लगता है कि सामान्य रूप से '=' वाइल्डकार्ड का उपयोग करते समय 'जैसे' से अधिक तेज होता है। यह पारंपरिक ज्ञान प्रतीत होता है। हालाँकि, मान लीजिए कि मेरे पास एक स्तंभ है जिसमें सीमित संख्या में विभिन्न निश्चित, हार्डकोड, varchar आइडेंटिफ़ायर हैं, और मैं उनमें से किसी एक से मेल खाती सभी पंक्तियों का चयन करना चाहता हूं:

select * from table where value like 'abc%'

तथा

select * from table where value = 'abcdefghijklmn'

'लाइक' को केवल एक मैच खोजने के लिए पहले तीन वर्णों का परीक्षण करना चाहिए, जबकि '=' को पूरे स्ट्रिंग की तुलना करनी चाहिए। इस मामले में यह मुझे प्रतीत होता है कि 'जैसे' से एक फायदा होगा, अन्य सभी चीजें समान होंगी।

यह एक सामान्य, अकादमिक प्रश्न के रूप में अभिप्रेत है, और इसलिए इस पर कोई फर्क नहीं पड़ता कि कौन सा DB है, लेकिन यह SQL Server 2005 का उपयोग कर उत्पन्न हुआ।


23
आपके द्वारा छोड़ी गई एक प्रमुख चीज़ valueको अनुक्रमित किया जाता है या नहीं । यदि यह है, तो =एक साधारण लुकअप है जिसमें कोई टेबल स्कैन आवश्यक नहीं है और LIKEयह आपके द्वारा फेंके गए किसी भी बयान से पैंट को हरा देगा ।
डैनियल डीपोलो

7
@ डैनियल मुझे लगता है कि यह गलत है। एक LIKEअंत में एक वाइल्डकार्ड के साथ SARGable है और इस तरह एक सीमा एक सूचकांक, दृष्टि में कोई तालिका स्कैन पर तलाश प्रदर्शन करेंगे। वह रेंज की तलाश एक =बयान के साथ काफी आसानी से प्रतिस्पर्धा कर सकती है , और कई मामलों में (जैसे कि यदि सभी संतोषजनक पंक्तियां एक पृष्ठ पर हैं, तो एक असंभावित स्थिति नहीं) बिल्कुल एक ही प्रदर्शन हो सकता है, जिसमें समान संख्याओं को पढ़ता है।
ErikE

मेरी "अन्य सभी चीजें समान हैं" का उद्देश्य "अनुक्रमित या नहीं" मुद्दे को कवर करना था, लेकिन लगता है कि कम से कम कुछ विवादों में कितना अंतर होगा, अन्य उत्तरों पर मेरी टिप्पणियों के अनुसार।
मिकीफैगैन_बाहरExitOfSO

मेरा जवाब देखिए। मैंने शुरू में परीक्षण नहीं किया है और प्रदर्शन समान है (दोनों टेबल स्कैन बिल्कुल समान थे)। मैंने अपने परीक्षण परिदृश्य के लिए मान लिया कि इसे अनुक्रमित किया जाएगा, अन्यथा आप प्रदर्शन की परवाह क्यों करेंगे?
जेएनके

5
इस सवाल और जवाबों में 'लाइक' की सारी बातें हमें हाई स्कूल की लड़कियों के झुंड की तरह लगती हैं। जैसे, बिलकुल।
जूलियनआर

जवाबों:


64

Https://web.archive.org/web/20150209022016/http://myitforum.com/cs2/blogs/jnelson/archive/2007/11/16/108354.aspx देखें

वहां से बोली:

LIKE के साथ इंडेक्स के उपयोग के नियम इस तरह से शिथिल हैं:

  • यदि आपके फ़िल्टर मानदंड = का उपयोग करता है और फ़ील्ड अनुक्रमित है, तो सबसे अधिक संभावना है कि यह INDEX / CLUSTEREDEXEXEK का उपयोग करेगा

  • यदि आपके फ़िल्टर मापदंड LIKE का उपयोग करते हैं, बिना वाइल्डकार्ड के साथ (जैसे अगर आपके पास एक वेब रिपोर्ट में पैरामीटर था कि COULD में एक% है लेकिन आप इसके बजाय पूर्ण स्ट्रिंग का उपयोग करते हैं), तो यह सूचकांक का उपयोग करने के लिए # 1 के रूप में संभावना है। बढ़ी हुई लागत लगभग कुछ भी नहीं है।

  • यदि आपके फ़िल्टर मानदंड LIKE का उपयोग करते हैं, लेकिन शुरुआत में वाइल्डकार्ड के साथ (जैसा कि Name0 LIKE '% UTER' में) यह इंडेक्स का उपयोग करने की बहुत कम संभावना है, लेकिन यह अभी भी कम से कम एक पूर्ण या आंशिक सीमा पर INDEX SCAN का प्रदर्शन कर सकता है। अनुक्रमणिका।

  • फिर भी, यदि आपके फ़िल्टर मापदंड LIKE का उपयोग करते हैं, लेकिन एक STRING FIRST के साथ शुरू होता है और कहीं-कहीं वाइल्डकार्ड हैं (जैसा कि Name0 LIKE 'COMP% ER' में), तो SQL केवल पंक्तियों को जल्दी से उपयोग करने के लिए एक INDEX SEEK का उपयोग कर सकता है जिसमें पहले समान शुरुआती अक्षर, और फिर एक सटीक मिलान के लिए उन पंक्तियों के माध्यम से देखें।

(यह भी ध्यान रखें, SQL इंजन अभी भी एक अनुक्रमणिका का उपयोग नहीं कर सकता है जिस तरह से आप उम्मीद कर रहे हैं, यह इस बात पर निर्भर करता है कि आपकी क्वेरी में क्या चल रहा है और आप किन तालिकाओं में शामिल हो रहे हैं। SQL इंजन आपके पुन: लिखने का अधिकार सुरक्षित रखता है। इस तरह से डेटा प्राप्त करने के लिए थोड़ा क्वेरी करें जो यह सोचता है कि यह सबसे कुशल है और इसमें INDEX SCEK के बजाय INDEX SCAN शामिल हो सकता है)


1
यह लिंक मृत है
baxx

2
@baxx लिंक की एक कॉपी वेनबैक मशीन में उपलब्ध है। web.archive.org/web/20150209022016/http://myitforum.com/cs2/…
alphabet5

45

यह एक औसत दर्जे का अंतर है।

निम्नलिखित चलाएँ:

Create Table #TempTester (id int, col1 varchar(20), value varchar(20))
go

INSERT INTO #TempTester (id, col1, value)
VALUES
(1, 'this is #1', 'abcdefghij')
GO

INSERT INTO #TempTester (id, col1, value)
VALUES
(2, 'this is #2', 'foob'),
(3, 'this is #3', 'abdefghic'),
(4, 'this is #4', 'other'),
(5, 'this is #5', 'zyx'),
(6, 'this is #6', 'zyx'),
(7, 'this is #7', 'zyx'),
(8, 'this is #8', 'klm'),
(9, 'this is #9', 'klm'),
(10, 'this is #10', 'zyx')
GO 10000

CREATE CLUSTERED INDEX ixId ON #TempTester(id)CREATE CLUSTERED INDEX ixId ON #TempTester(id)

CREATE NONCLUSTERED INDEX ixTesting ON #TempTester(value)

फिर:

SET SHOWPLAN_XML ON

फिर:

SELECT * FROM #TempTester WHERE value LIKE 'abc%'

SELECT * FROM #TempTester WHERE value = 'abcdefghij'

परिणामी निष्पादन योजना आपको दिखाती है कि पहले ऑपरेशन की लागत, LIKEतुलना, तुलना की तुलना में लगभग 10 गुना अधिक महंगा है =

यदि आप एक =तुलना का उपयोग कर सकते हैं , तो कृपया ऐसा करें।


2
यह वास्तव में परीक्षण के लिए +1। बस शोपन को देखने से पूरी कहानी नहीं बताई जा सकती है। मैं अपना खुद का कुछ परीक्षण करने जा रहा हूं और अगर मुझे कुछ भी अप्रत्याशित लगता है तो मैं सभी को बता दूंगा।
टॉम एच

1
टॉम - सच है, लेकिन इसने मुझे एक संकेत दिया कि दोनों को पर्दे के पीछे एक ही तरह से संसाधित नहीं किया गया था।
JNK

1
निष्पादन योजना में दिखाई गई लागत गलत है। वे वास्तविक प्रदर्शन को प्रतिबिंबित नहीं करते हैं। पहली योजना में वे 19.95एक अतिरिक्त 19 महत्वपूर्ण लुकअप में SQL सर्वर लागतों के अनुमानित उपद्रव पर आधारित होते हैं जो कभी भी वास्तविकता में नहीं होते हैं (यहां तक ​​कि वास्तविक निष्पादन योजना में दिखाई गई लागत अनुमानित उप वृक्ष लागत पर आधारित होती है)
मार्टिन स्मिथ

मैंने अभी-अभी आपका परीक्षण और साथ ही लगभग 1M पंक्तियों के साथ किया है और दोनों ही मामलों में प्रदर्शन और क्वेरी योजनाएँ समान थीं। यह SQL 2008 पर है क्योंकि मेरे पास इस मशीन पर 2005 नहीं है।
टॉम एच

1
@JNK - बस इसे आज़माया - एक नगण्य अंतर है, असमानता एक ही है, हालांकि। के लिए 327ms LIKE, के लिए 203ms =। मुझे उम्मीद है कि अगर मैंने अधिक परीक्षण चलाए और सटीक औसत लिया, तो # टैम्प और वास्तविक तालिका के बीच कोई वास्तविक अंतर नहीं होगा।
एक

13

आपको यह भी ध्यान रखना चाहिए कि उपयोग करते समय like, कुछ sql फ्लेवर इंडेक्स की उपेक्षा करेंगे, और यह प्रदर्शन को मार देगा। यह विशेष रूप से सच है यदि आप अपने उदाहरण की तरह "स्टार्ट विथ" पैटर्न का उपयोग नहीं करते हैं।

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

यह कहा जा रहा है, "पैटर्न के साथ शुरू होता है" और sql सर्वर में अनुकूलित होता है। यह तालिका सूचकांक का उपयोग करेगा । EF 4.0 ने इसी कारण से इसके likeलिए स्विच किया StartsWith


2
जब इसके पैटर्न क्वेरी का हिस्सा होता है और वाइल्डकार्ड अनुगामी होता है, तो इसके नमक के लायक कोई रिलेशनल डेटाबेस एक इंडेक्स को अनदेखा नहीं करेगा। यदि आप मान को बाध्य कर रहे हैं तो यह एक अलग कहानी हो सकती है और डेटाबेस क्वेरी तैयारी से अलग बाइंडिंग का समर्थन करता है।
डेव डब्ल्यू। स्मिथ

यही मेरा पेट मुझे भी बता रहा है, लेकिन मुझे इस संबंध में sql सर्वर के साथ केवल हाथ का अनुभव है, इसलिए मैंने इस पर विशेष रूप से ध्यान केंद्रित किया।
ब्लाइंड

7

यदि valueएकतरफा है, तो दोनों तालिका-स्कैन में परिणाम करते हैं। इस परिदृश्य में प्रदर्शन अंतर नगण्य होगा।

यदि valueअनुक्रमित किया जाता है, जैसा कि डैनियल अपनी टिप्पणी में बताते हैं, तो =एक अनुक्रमणिका लुकअप में परिणाम होगा जो ओ (लॉग एन) प्रदर्शन है। अनुक्रमणिका के आंशिक स्कैन के परिणामस्वरूप LIKE होगा (सबसे अधिक संभावना है - यह कि यह कितना चयनात्मक है) पर निर्भर करता है >= 'abc'और < 'abd'इसके लिए अधिक प्रयास की आवश्यकता होगी =

ध्यान दें कि मैं यहां SQL सर्वर की बात कर रहा हूं - सभी DBMS LIKE के साथ अच्छे नहीं होंगे।


मुझे नहीं लगता कि आपको पता है कि द्विआधारी खोज कैसे काम करती है। यदि मामले में पैटर्न पैटर्न (और ऐसा करता है) को पहचानता है तो =मामला और मामला दोनों like '...%'समान हैं, क्योंकि दोनों ही मामलों में उप-पेड़ों को तुलना संबंधों के आधार पर चुना जाता है।
ब्लाइंड

ओह मेरे पास है। LIKE सबसे अधिक खराब व्यवहार करेगा, हालाँकि यह अभी भी O (log N) होगा यदि चयनात्मकता काफी अधिक है - O (log N) यह पता लगाने के लिए कि आंशिक स्कैन कहाँ से शुरू किया जाए, तो आगे की एक संख्या इंडेक्स तक पढ़ती है अंतिम बिंदु 'abd'पर पहुंच गया है।
एक

हां, लेकिन ओपी का उदाहरण मानता है कि उस सीमा में केवल एक ही मूल्य है, इसलिए यह ध्यान में रखते हुए कि तुलना समान होगी।
ब्लाइंडी

मान्य बिंदु - यह पूरी तरह से स्पष्ट नहीं है कि यह वही है जो ओपी कह रहा था, लेकिन मुझे लगता है कि ऐसा होने की संभावना अधिक है। उस स्थिति में, प्रदर्शन बहुत अधिक समान होगा।
एक

एक LIKE की रेंज की संभावना काफी हद तक = स्टेटमेंट के साथ बहुत अच्छी तरह से प्रतिस्पर्धा करेगी, और कई मामलों में (जैसे कि सभी संतोषजनक पंक्तियाँ एक पृष्ठ पर हों, एक असंभावित स्थिति नहीं) बिल्कुल एक ही प्रदर्शन हो सकता है, एक ही नंबर की रीडिंग को मिलाकर । मुझे लगता है कि यह कहना "अधिक प्रयास की आवश्यकता होगी" एक गलत कंबल बयान है।
ErikE

6

आप गलत सवाल पूछ रहे हैं। डेटाबेस में ऑपरेटर का प्रदर्शन नहीं है जो मायने रखता है, हमेशा अभिव्यक्ति की SARGability , और समग्र क्वेरी की coverability है। ऑपरेटर का प्रदर्शन अपने आप में काफी हद तक अप्रासंगिक है।

तो, SARGability के संदर्भ में कैसे करें LIKEऔर =तुलना करें? LIKE, जब एक अभिव्यक्ति के साथ प्रयोग किया जाता है जो एक स्थिरांक के साथ शुरू नहीं होता है (उदाहरण के लिए। जब ​​इस्तेमाल किया जाता है LIKE '%something') परिभाषा गैर-सरगाबेल द्वारा होता है। लेकिन यह बनाता है =या LIKE 'something%'SARGable? नहीं। SQL प्रदर्शन के बारे में किसी भी प्रश्न के साथ उत्तर पाठ की क्वेरी के साथ नहीं है, लेकिन स्कीमा तैनात है। यदि कोई सूचकांक उन्हें संतुष्ट करने के लिए मौजूद है तो ये अभिव्यक्ति SARGable हो सकती है।

तो, सच तो यह है, कहा जा वहाँ के बीच छोटे मतभेद हैं =और LIKE। लेकिन यह पूछना कि क्या SQL में एक ऑपरेटर या अन्य ऑपरेटर 'तेज' है, यह पूछने की तरह है कि 'क्या तेज होता है, एक लाल कार या एक नीली कार?' आपको ईबे से इंजन के आकार और वेजिकल वेट के बारे में सवाल पूछने चाहिए, रंग के बारे में नहीं ... संबंधपरक तालिकाओं के अनुकूलन के बारे में सवालों के जवाब के लिए, देखने की जगह आपके सूचकांक और WHERE क्लॉज (और अन्य क्लॉस) में आपके भाव हैं, लेकिन आमतौर पर कहां से शुरू होता है)।


5

Mysql 5.5 का उपयोग करते हुए एक व्यक्तिगत उदाहरण: मेरे पास 2 तालिकाओं, 3 मिलियन पंक्तियों में से एक और 10 हजार पंक्तियों में से एक के बीच एक आंतरिक जुड़ाव था।

नीचे (कोई वाइल्डकार्ड) के रूप में एक सूचकांक पर एक का उपयोग करते समय, लगभग 30 सेकंड लग गए:

where login like '12345678'

'व्याख्या' का उपयोग कर मुझे मिलता है:

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

एक ही क्वेरी पर '=' का उपयोग करते समय, लगभग 0.1 सेकंड लगते हैं:

where login ='600009'

'व्याख्या' का उपयोग कर मुझे मिलता है:

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

जैसा कि आप देख सकते हैं, likeसूचकांक की तलाश को पूरी तरह से रद्द कर दिया गया है, इसलिए क्वेरी को 300 गुना अधिक समय लगा।


आप इसकी पुष्टि करने के लिए केवल निष्पादन योजना देख सकते हैं
LittleBobbyTables - Au Revoir

धन्यवाद @LittleBobbyTables उस पर एक नजर होगी।
आरिस

मुझे नहीं पता कि यह मेरे हालिया संस्करण (5.7) के कारण है, लेकिन LIKE यहां मेरे अद्वितीय सूचकांक को नहीं तोड़ता है।
सेबास

0

शायद आप पूर्ण पाठ खोज के बारे में देख रहे हैं ।

पूर्ण-पाठ खोज के विपरीत, LIKE Transact-SQL विधेय केवल चरित्र पैटर्न पर काम करता है। साथ ही, आप स्वरूपित बाइनरी डेटा क्वेरी के लिए LIKE विधेय का उपयोग नहीं कर सकते। इसके अलावा, असंरचित पाठ डेटा की एक बड़ी राशि के खिलाफ एक LIKE क्वेरी समान डेटा के विरुद्ध एक पूर्ण-पाठ क्वेरी की तुलना में बहुत धीमी है । पाठ डेटा की लाखों पंक्तियों के खिलाफ एक LIKE क्वेरी को वापस आने में कुछ मिनट लग सकते हैं; जबकि एक पूर्ण-पाठ क्वेरी केवल उसी डेटा के विरुद्ध सेकंड या उससे कम समय ले सकती है, जो पंक्तियों की संख्या पर निर्भर करती है।


-1

पहली चीजें पहले ,

वे हमेशा समान नहीं होते हैं

    select 'Hello' from dual where 'Hello  ' like 'Hello';

    select 'Hello' from dual where 'Hello  ' =  'Hello';

जब चीजें हमेशा समान नहीं होती हैं, तो उनके प्रदर्शन के बारे में बात करना उतना प्रासंगिक नहीं होता है।

यदि आप स्ट्रिंग्स और केवल चार चर पर काम कर रहे हैं, तो आप प्रदर्शन के बारे में बात कर सकते हैं। लेकिन आम तौर पर विनिमेय होने के नाते "और" = का उपयोग न करें।

जैसा कि आपने कई पदों (ऊपर और अन्य प्रश्नों) में देखा होगा, ऐसे मामलों में जब वे समान होते हैं जैसे कि पैटर्न मिलान (टकराव) के कारण धीमी गति होती है


यदि 'Hello 'एक VARCHAR(डिफ़ॉल्ट) आप सही हैं, लेकिन अगर यह CHARआप नहीं हैं। यह करने के लिए कास्ट CHAR(7)और दोनों सच लौटें। इसके अलावा, नरक क्या आप कर रहे हैं जहाँ आप TRIMअपने varchars आईएनजी नहीं कर रहे हैं ? (ध्यान दें: यह कम से कम मामला है SQL Server 2008r2)
abluejelly
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.