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% के भीतर थे।
क्या कोई एसक्यूएल दक्षता विशेषज्ञ बाहर है जो यह समझा सकता है कि खोज स्ट्रिंग के अंत में वाइल्डकार्ड शुरुआत से बेहतर अभ्यास क्यों करेगा, और शायद स्ट्रिंग की शुरुआत और अंत में वाइल्डकार्ड के साथ क्यों खोज करना तेज था शुरुआत में वाइल्डकार्ड होने से?
क्या करना चाहते हैं आप प्रत्येक परीक्षण से पहले बफर और कैश साफ़ करते हैं? –
हां, प्रत्येक क्वेरी का परीक्षण करने से पहले हमने यह सुनिश्चित करने के लिए सर्वर को रीबूट किया कि यह एक उचित परीक्षण था। – Jeremy1026
रिवर्स() दृष्टिकोण एक टेबल स्कैन को मजबूर करेगा क्योंकि प्रत्येक पंक्ति को उलट दिया जाना चाहिए, इसका आमतौर पर प्रीफिक्स-वाइल्डकार्ड + प्री-कंप्यूटेड रिवर्स कॉलम –