9

LIKE और वाइल्डकार्ड का उपयोग कर एमएस एसक्यूएल डेटाबेस खोजने के लिए हाल ही में सबसे प्रभावी तरीके से काम पर बहस हुई है। हम %abc%, %abc, और abc% का उपयोग कर तुलना कर रहे हैं। एक व्यक्ति ने कहा है कि आपको हमेशा टर्म के अंत में वाइल्डकार्ड होना चाहिए (abc%)। इसलिए, उनके अनुसार, अगर हम "एबीसी" में समाप्त होने वाली कुछ चीज़ खोजना चाहते हैं तो यह रिवर्स (कॉलम) जैसे रिवर्स ('% abc') का उपयोग करने के लिए सबसे अधिक कुशल होगा।एसक्यूएल वाइल्डकार्ड खोज - क्षमता?

मैं एसक्यूएल सर्वर 2008 (R2) का उपयोग निम्नलिखित बयानों में से प्रत्येक की तुलना करने के लिए एक परीक्षण की स्थापना:

select * from CLMASTER where ADDRESS like '%STREET' 
select * from CLMASTER where ADDRESS like '%STREET%' 
select * from CLMASTER where ADDRESS like reverse('TEERTS%') 
select * from CLMASTER where reverse(ADDRESS) like reverse('%STREET') 

CLMASTER लगभग 500,000 रिकॉर्ड, वहाँ 7400 के बारे में पता जिन्हें अंत "स्ट्रीट" कर रहे हैं रखती है, और के बारे में 8,500 पते जिनमें "स्ट्रीट" है, लेकिन अंत में जरूरी नहीं है। प्रत्येक टेस्ट रन में 2 सेकंड लगते थे और वे सभी %STREET% को छोड़कर समान मात्रा में पंक्तियों को वापस लौटाते थे, जिन्हें अतिरिक्त 900 या तो परिणाम मिलते थे क्योंकि इसने उन पते को उठाया जिनके अंत में एक अपार्टमेंट नंबर था।

के बाद से एसक्यूएल सर्वर परीक्षण निष्पादन समय मैं PHP में चले गए, जहां मैं कई परीक्षण जल्दी से चलाने के लिए निम्नलिखित कोड का इस्तेमाल किया है, प्रत्येक बयान में स्विच कर देंगे, में कोई अंतर नहीं दिखा था:

<?php 

    require_once("config.php"); 
    $connection = odbc_connect($connection_string, $U, $P); 

    for ($i = 0; $i < 500; $i++) { 
    $m_time = explode(" ",microtime()); 
    $m_time = $m_time[0] + $m_time[1]; 

    $starttime = $m_time; 

    $Message=odbc_exec($connection,"select * from CLMASTER where ADDRESS like '%STREET%'"); 
    $Message=odbc_result($Message,1); 

    $m_time = explode(" ",microtime()); 
    $m_time = $m_time[0] + $m_time[1]; 

    $endtime = $m_time; 

    $totaltime[] = ($endtime - $starttime); 

} 

odbc_close($connection); 

echo "<b>Test took and average of:</b> ".round(array_sum($totaltime)/count($totaltime),8)." seconds per run.<br>"; 
echo "<b>Test took a total of:</b> ".round(array_sum($totaltime),8)." seconds to run.<br>"; 

?> 

के परिणाम एसक्यूएल सर्वर में परीक्षण करते समय यह परीक्षण परिणाम के रूप में संदिग्ध था।

%STREET 166.5823 सेकंड (.3331 औसत प्रति क्वेरी) में पूरा हुआ, और औसतन 500 परिणाम पाए गए .0228।

%STREET% 14 9.4500 सेकंड (.2989 औसत प्रति क्वेरी) में पूरा हुआ, और औसतन 500 परिणाम पाए गए .0177। (परिणामस्वरूप तेज़ समय क्योंकि यह अन्य समय की तुलना में अन्य परिणामों की तुलना में अधिक परिणाम पाता है।)

reverse(ADDRESS) like reverse('%STREET') 134.0115 सेकंड (.2680 औसत प्रति क्वेरी) में पूरा हुआ, और औसतन 500 परिणाम .0183 सेकंड में पाए गए।

reverse('TREETS%') 167,6960 सेकंड में पूरा किया (प्रति क्वेरी 0.3354 औसत), और औसतन 500 परिणाम .0229 में पाया।

हमें यह परीक्षण दिखाने की उम्मीद है कि %STREET% सबसे धीमा समग्र होगा, जबकि यह वास्तव में चलाने के लिए सबसे तेज़ था, और 500 परिणामों को वापस करने का सबसे अच्छा औसत समय था। जबकि सुझाए गए reverse('%STREET') समग्र रूप से चलाने के लिए सबसे तेज़ थे, लेकिन 500 परिणामों को वापस करने के लिए समय में थोड़ा धीमा था।

अतिरिक्त मज़े: एक सहकर्मी सर्वर पर प्रोफाइलर चला रहा था, जबकि हम परीक्षण चला रहे थे और पाया कि डबल वाइल्डकार्ड के उपयोग ने सीपीयू उपयोग में उल्लेखनीय वृद्धि की, जबकि अन्य परीक्षण एक-दूसरे के 1-2% के भीतर थे।

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

+0

क्या करना चाहते हैं आप प्रत्येक परीक्षण से पहले बफर और कैश साफ़ करते हैं? –

+0

हां, प्रत्येक क्वेरी का परीक्षण करने से पहले हमने यह सुनिश्चित करने के लिए सर्वर को रीबूट किया कि यह एक उचित परीक्षण था। – Jeremy1026

+1

रिवर्स() दृष्टिकोण एक टेबल स्कैन को मजबूर करेगा क्योंकि प्रत्येक पंक्ति को उलट दिया जाना चाहिए, इसका आमतौर पर प्रीफिक्स-वाइल्डकार्ड + प्री-कंप्यूटेड रिवर्स कॉलम –

उत्तर

16

होने स्ट्रिंग के अंत में वाइल्डकार्ड, 'abc%' की तरह, मदद मिलेगी अगर उस स्तंभ, अनुक्रमित रहे थे के रूप में यह रिकॉर्ड जो 'abc' के साथ शुरू और बाकी सब कुछ अनदेखी करने के लिए सीधे की तलाश करने में सक्षम होगा। शुरुआत में वाइल्ड कार्ड होने का मतलब है कि अनुक्रमण के बावजूद इसे हर पंक्ति को देखना होगा।

अच्छा विवरण here अधिक स्पष्टीकरण के साथ।

+2

जो विस्तार से, इसका मतलब है कि 'abc%' जैसे 'रिवर्स (कोल)' जैसे कुछ करना एक बुरा विचार है। –

+0

हां, 'रिवरसी 'या अनुक्रमित कॉलम को बदलने वाले किसी भी अन्य गणना का मतलब है कि आप स्केबिलिटी खो देते हैं। – Bort

+0

प्रदान किए गए उत्तर/टिप्पणियों के लिए धन्यवाद – Jeremy1026

1

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

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

तो, उपर्युक्त उद्धरण भी बताता है कि क्यों वहाँ एक विशाल प्रोसेसर कील था जब दो वाइल्डकार्ड चल रहा है। यह केवल घटना के द्वारा तेजी से पूरा हुआ क्योंकि अक्षमता को कवर करने के लिए पर्याप्त अश्वशक्ति है। किसी क्वेरी पर प्रदर्शन निर्धारित करने का प्रयास करते समय आप सर्वर के संसाधनों की बजाय क्वेरी के निष्पादन को देखना चाहते हैं क्योंकि वे भ्रामक हो सकते हैं। अगर मेरे पास मौसम व्यर्थ सेवा करने के लिए पर्याप्त अश्वशक्ति वाला सर्वर है और मैं 500,000 पंक्तियों के रूप में छोटे टेबल पर क्वेरी चला रहा हूं तो परिणाम भ्रामक होने जा रहे हैं।

कम तथ्य यह है कि माइक्रोसॉफ्ट अपने जवाब में उद्धृत किया, जब प्रदर्शन विश्लेषण कर रही है, कैसे कार्य योजना लागू करके पढ़ना सीख में गोता लेने पर विचार। यह एक निवेश है और बहुत शुष्क है, लेकिन यह लंबे समय तक इसके लायक होगा।

हालांकि, जो भी संकेत दे रहा था कि पिछला वाइल्डकार्ड केवल अधिक कुशल है, सही है।

+0

@ जेरेमी 1026 - मैंने सर्वर के प्रदर्शन के परिणामों के परिणामों के बारे में थोड़ा और स्पष्टीकरण के साथ अपना उत्तर अपडेट कर दिया है। आपके द्वारा प्रदान किए गए उत्तर के लिए –

+0

धन्यवाद। – Jeremy1026

+0

@ जेरेमी 1026 - कोई समस्या नहीं। –

2

केवल एक Like चरित्र स्ट्रिंग के अंत में वाइल्डकार्ड एक सूचकांक का उपयोग करेगा।

यदि आप एक चरित्र स्ट्रिंग के आगे और पीछे वाइल्डकार्ड की गति में सुधार करना चाहते हैं तो आपको एफटीएस Contains का उपयोग करना चाहिए। see this related SO post regarding Contains versus Like भी।

+0

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

-2

एमएस एसक्यूएल में, यदि आप नाम उन 'एबीसी' के साथ समाप्त कर रहे हैं करना चाहते हैं, तो यू क्वेरी के नीचे की तरह (मान लीजिए तालिका नाम student है) हो सकता है

select * from student where student_name like'%[ABC]' 

तो यह उन दे देंगे नाम 'ए', 'बी', 'सी' के साथ समाप्त होता है।

2) यू नाम के साथ शुरू कर रहे हैं जो करना चाहते हैं, तो 'एबीसी' का मतलब है,

select * from student where student_name like '[ABC]%' 

3) यदि u नाम जो बीच में है 'एबीसी'

select * from student where student_name like '%[ABC]%' 
संबंधित मुद्दे