बनाम बनाम SQL SQL क्लाज में


150

बड़े डेटाबेस के साथ काम करते समय, जो बेहतर प्रदर्शन करता है, INया ORएसक्यूएल Where-क्लॉज में?

क्या उनके निष्पादित होने के तरीके के बारे में कोई अंतर है?


मेरा पहला अनुमान यह होगा कि OR बेहतर प्रदर्शन करता है, जब तक कि SQL इंजन दृश्य में या उसके पीछे नहीं जाता। क्या आपने इन दोनों की क्वेरी योजना देखी है?
राज

जवाबों:


170

मुझे लगता है कि आप निम्नलिखित के बीच प्रदर्शन अंतर जानना चाहते हैं:

WHERE foo IN ('a', 'b', 'c')
WHERE foo = 'a' OR foo = 'b' OR foo = 'c'

MySQL के मैनुअल के अनुसार यदि मान निरंतर INसूची को क्रमबद्ध करते हैं और फिर एक बाइनरी खोज का उपयोग करते हैं। मुझे लगता है कि ORकोई विशेष क्रम में एक-एक करके उनका मूल्यांकन करता है। तो INकुछ परिस्थितियों में तेज है।

यह जानने का सबसे अच्छा तरीका है कि आपके डेटाबेस पर दोनों को आपके विशिष्ट डेटा के साथ प्रोफ़ाइल किया जाए ताकि यह देखा जा सके कि कौन सा तेज़ है।

मैंने 1000000 पंक्तियों के साथ एक MySQL पर दोनों की कोशिश की। जब स्तंभ को अनुक्रमित किया जाता है तो प्रदर्शन में कोई अंतर नहीं होता है - दोनों लगभग तुरंत होते हैं। जब स्तंभ अनुक्रमित नहीं होता है तो मुझे ये परिणाम मिले हैं:

SELECT COUNT(*) FROM t_inner WHERE val IN (1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000);
1 row fetched in 0.0032 (1.2679 seconds)

SELECT COUNT(*) FROM t_inner WHERE val = 1000 OR val = 2000 OR val = 3000 OR val = 4000 OR val = 5000 OR val = 6000 OR val = 7000 OR val = 8000 OR val = 9000;
1 row fetched in 0.0026 (1.7385 seconds)

तो इस मामले में OR का उपयोग करने की विधि लगभग 30% धीमी है। अधिक शब्द जोड़ने से अंतर बड़ा हो जाता है। परिणाम अन्य डेटाबेस और अन्य डेटा पर भिन्न हो सकते हैं।


20
यदि आशावादी इसके नमक के लायक है, तो उन्हें भी ऐसा ही करना चाहिए।
जैनिक बर्नेट

27
@inflagranti: कोई भी आशावादी दुर्भाग्यपूर्ण नहीं है। ऑप्टिमाइज़र बेहद जटिल कार्यक्रम हैं और प्रत्येक कार्यान्वयन की अपनी ताकत और कमजोरियां होंगी। यही कारण है कि मैं कहता हूं कि आपको एक विशिष्ट कार्यान्वयन पर प्रोफ़ाइल करना चाहिए। मुझे लगता है कि INविधि की अतिरिक्त संरचना संभवतः संबंधित ORखंडों के एक पूरे समूह की तुलना में अनुकूलन करना आसान बनाती है । मुझे आश्चर्य होगा कि अगर कोई इंजन है जहां ORविधि तेज है, लेकिन मुझे आश्चर्य नहीं है कि ऐसे समय होते हैं जब OR धीमा होता है।
मार्क बायर्स

2
@MarkBenders अनुकूलक हमेशा ORएक के साथ कई एस स्थानापन्न नहीं कर सकता है IN?
tttam

36

पता लगाने का सबसे अच्छा तरीका निष्पादन योजना को देख रहा है।


मैंने इसे ओरेकल के साथ आजमाया , और यह बिल्कुल वैसा ही था।

CREATE TABLE performance_test AS ( SELECT * FROM dba_objects );

SELECT * FROM performance_test
WHERE object_name IN ('DBMS_STANDARD', 'DBMS_REGISTRY', 'DBMS_LOB' );

भले ही क्वेरी का उपयोग करें IN, निष्पादन योजना का कहना है कि यह उपयोग करता है OR:

--------------------------------------------------------------------------------------    
| Id  | Operation         | Name             | Rows  | Bytes | Cost (%CPU)| Time     |    
--------------------------------------------------------------------------------------    
|   0 | SELECT STATEMENT  |                  |     8 |  1416 |   163   (2)| 00:00:02 |    
|*  1 |  TABLE ACCESS FULL| PERFORMANCE_TEST |     8 |  1416 |   163   (2)| 00:00:02 |    
--------------------------------------------------------------------------------------    

Predicate Information (identified by operation id):                                       
---------------------------------------------------                                       

   1 - filter("OBJECT_NAME"='DBMS_LOB' OR "OBJECT_NAME"='DBMS_REGISTRY' OR                
              "OBJECT_NAME"='DBMS_STANDARD')                                              

1
ओरेकल में क्या होता है यदि आपके पास 3 से अधिक मान हैं जो आप परीक्षण कर रहे हैं? क्या आप जानते हैं कि ओरेकल माईएसक्यूएल के समान बाइनरी सर्च ऑप्टिमाइज़ेशन करने में असमर्थ है या क्या यह दोनों मामलों में प्रदर्शन करता है?
मार्क बायर्स

2
@ मार्कर्स बायर्स: मैंने एक ही क्वेरी को 10 मानों के साथ आज़माया, फिर भी वही परिणाम। ध्यान दें, कि ऑप्टिमाइज़र ने वर्णमाला क्रम में मेरे मूल्यों का सहारा लिया। मुझे आश्चर्य नहीं होगा अगर ओरेकल ने उस फिल्टर का कुछ आंतरिक अनुकूलन किया ...
पीटर लैंग

5
ओरेकल में एक INLIST ITERATORऑपरेशन भी होता है , जिसे यह चुनता है कि क्या कोई इंडेक्स है जो इसका उपयोग कर सकता है। फिर भी, जब मैं इसे बाहर की कोशिश की, दोनों INऔर ORएक ही निष्पादन योजना के साथ खत्म।
चेरन शुनमुगवेल

7

OR ऑपरेटर को IN निर्माण की तुलना में बहुत अधिक जटिल मूल्यांकन प्रक्रिया की आवश्यकता होती है क्योंकि यह कई स्थितियों को अनुमति देता है, न कि IN के समान।

यहाँ एक प्रकार है जिसे आप OR के साथ उपयोग कर सकते हैं लेकिन यह IN: अधिक से अधिक संगत नहीं है। अधिक या बराबर, कम, कम या बराबर, LIKE और कुछ और जैसे oracle REGEXP_LIKE। इसके अलावा विचार करें कि स्थितियां हमेशा समान मूल्य की तुलना नहीं कर सकती हैं।

क्वेरी ऑप्टिमाइज़र के लिए IN ऑपरेटर को प्रबंधित करना आसान है क्योंकि केवल एक ऐसा निर्माण है जो OR ऑपरेटर को एक ही मान पर = ऑपरेटर के साथ कई शर्तों पर परिभाषित करता है। यदि आप OR ऑपरेटर का उपयोग करते हैं, तो ऑप्टिमाइज़र यह विचार नहीं कर सकता है कि आप हमेशा एक ही मूल्य पर = ऑपरेटर का उपयोग कर रहे हैं और, यदि यह अधिक गहरा और बहुत अधिक जटिल विस्तार नहीं करता है, तो यह संभवतः बाहर कर सकता है कि केवल हो सकता है = पहले से ही वर्णित बाइनरी खोज की तरह अनुकूलित खोज विधियों के परिणामी समावेश के साथ सभी शामिल स्थितियों पर समान मूल्यों के लिए ऑपरेटर।

[संपादित करें] संभवतः एक ऑप्टिमाइज़र मूल्यांकन प्रक्रिया में अनुकूलित को लागू नहीं कर सकता है, लेकिन यह इस बात को बाहर नहीं करता है कि एक बार ऐसा हो सकता है (डेटाबेस संस्करण अपग्रेड के साथ)। इसलिए यदि आप OR ऑपरेटर का उपयोग करते हैं जो आपके मामले में अनुकूलित विस्तार का उपयोग नहीं किया जाएगा।


6

मुझे लगता है कि ओरेकल कम कुशल एक (जो भी है) को दूसरे में बदलने के लिए पर्याप्त स्मार्ट है। इसलिए मुझे लगता है कि उत्तर को प्रत्येक की पठनीयता पर निर्भर होना चाहिए (जहां मुझे लगता है कि INस्पष्ट रूप से जीतता है)


2

ORसमझ में आता है (पठनीयता के दृष्टिकोण से), जब तुलना करने के लिए कम मूल्य होते हैं। INउपयोगी esp है। जब आपके पास एक गतिशील स्रोत होता है, जिसके साथ आप चाहते हैं कि मूल्यों की तुलना की जाए।

एक अन्य विकल्प JOINअस्थायी तालिका के साथ उपयोग करना है ।
मुझे नहीं लगता कि प्रदर्शन में कोई समस्या होनी चाहिए, बशर्ते आपके पास आवश्यक सूचकांक हों।


-2

मैंने OR (350) की एक बड़ी संख्या में SQL क्वेरी की। Postgres इसे 437.80ms करते हैं

का उपयोग करें

अब IN का उपयोग करें:

में प्रयोग करें

23.18ms


4
यह काफी एक ही बात नहीं है, क्योंकि आपने IN उपवाक्य के लिए एक उपवर्ग का उपयोग किया है।
gliljas
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.