बड़े डेटाबेस के साथ काम करते समय, जो बेहतर प्रदर्शन करता है, IN
या OR
एसक्यूएल Where
-क्लॉज में?
क्या उनके निष्पादित होने के तरीके के बारे में कोई अंतर है?
बड़े डेटाबेस के साथ काम करते समय, जो बेहतर प्रदर्शन करता है, IN
या OR
एसक्यूएल Where
-क्लॉज में?
क्या उनके निष्पादित होने के तरीके के बारे में कोई अंतर है?
जवाबों:
मुझे लगता है कि आप निम्नलिखित के बीच प्रदर्शन अंतर जानना चाहते हैं:
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% धीमी है। अधिक शब्द जोड़ने से अंतर बड़ा हो जाता है। परिणाम अन्य डेटाबेस और अन्य डेटा पर भिन्न हो सकते हैं।
IN
विधि की अतिरिक्त संरचना संभवतः संबंधित OR
खंडों के एक पूरे समूह की तुलना में अनुकूलन करना आसान बनाती है । मुझे आश्चर्य होगा कि अगर कोई इंजन है जहां OR
विधि तेज है, लेकिन मुझे आश्चर्य नहीं है कि ऐसे समय होते हैं जब OR धीमा होता है।
OR
एक के साथ कई एस स्थानापन्न नहीं कर सकता है IN
?
पता लगाने का सबसे अच्छा तरीका निष्पादन योजना को देख रहा है।
मैंने इसे ओरेकल के साथ आजमाया , और यह बिल्कुल वैसा ही था।
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')
INLIST ITERATOR
ऑपरेशन भी होता है , जिसे यह चुनता है कि क्या कोई इंडेक्स है जो इसका उपयोग कर सकता है। फिर भी, जब मैं इसे बाहर की कोशिश की, दोनों IN
और OR
एक ही निष्पादन योजना के साथ खत्म।
OR ऑपरेटर को IN निर्माण की तुलना में बहुत अधिक जटिल मूल्यांकन प्रक्रिया की आवश्यकता होती है क्योंकि यह कई स्थितियों को अनुमति देता है, न कि IN के समान।
यहाँ एक प्रकार है जिसे आप OR के साथ उपयोग कर सकते हैं लेकिन यह IN: अधिक से अधिक संगत नहीं है। अधिक या बराबर, कम, कम या बराबर, LIKE और कुछ और जैसे oracle REGEXP_LIKE। इसके अलावा विचार करें कि स्थितियां हमेशा समान मूल्य की तुलना नहीं कर सकती हैं।
क्वेरी ऑप्टिमाइज़र के लिए IN ऑपरेटर को प्रबंधित करना आसान है क्योंकि केवल एक ऐसा निर्माण है जो OR ऑपरेटर को एक ही मान पर = ऑपरेटर के साथ कई शर्तों पर परिभाषित करता है। यदि आप OR ऑपरेटर का उपयोग करते हैं, तो ऑप्टिमाइज़र यह विचार नहीं कर सकता है कि आप हमेशा एक ही मूल्य पर = ऑपरेटर का उपयोग कर रहे हैं और, यदि यह अधिक गहरा और बहुत अधिक जटिल विस्तार नहीं करता है, तो यह संभवतः बाहर कर सकता है कि केवल हो सकता है = पहले से ही वर्णित बाइनरी खोज की तरह अनुकूलित खोज विधियों के परिणामी समावेश के साथ सभी शामिल स्थितियों पर समान मूल्यों के लिए ऑपरेटर।
[संपादित करें] संभवतः एक ऑप्टिमाइज़र मूल्यांकन प्रक्रिया में अनुकूलित को लागू नहीं कर सकता है, लेकिन यह इस बात को बाहर नहीं करता है कि एक बार ऐसा हो सकता है (डेटाबेस संस्करण अपग्रेड के साथ)। इसलिए यदि आप OR ऑपरेटर का उपयोग करते हैं जो आपके मामले में अनुकूलित विस्तार का उपयोग नहीं किया जाएगा।
OR
समझ में आता है (पठनीयता के दृष्टिकोण से), जब तुलना करने के लिए कम मूल्य होते हैं।
IN
उपयोगी esp है। जब आपके पास एक गतिशील स्रोत होता है, जिसके साथ आप चाहते हैं कि मूल्यों की तुलना की जाए।
एक अन्य विकल्प JOIN
अस्थायी तालिका के साथ उपयोग करना है ।
मुझे नहीं लगता कि प्रदर्शन में कोई समस्या होनी चाहिए, बशर्ते आपके पास आवश्यक सूचकांक हों।
मैंने OR (350) की एक बड़ी संख्या में SQL क्वेरी की। Postgres इसे 437.80ms करते हैं ।
अब IN का उपयोग करें:
23.18ms