MYSQL या बनाम प्रदर्शन में


180

मुझे आश्चर्य है कि निम्नलिखित के बीच प्रदर्शन के संबंध में कोई अंतर है या नहीं

SELECT ... FROM ... WHERE someFIELD IN(1,2,3,4)

SELECT ... FROM ... WHERE someFIELD between  0 AND 5

SELECT ... FROM ... WHERE someFIELD = 1 OR someFIELD = 2 OR someFIELD = 3 ... 

या क्या MySQL SQL को उसी तरह से ऑप्टिमाइज़ करेगा जैसे कंपाइलर कोड को ऑप्टिमाइज़ करेगा?

संपादित करें: टिप्पणियों में बताए गए कारणों के लिए 's' ANDको बदल दिया है OR


Im इस बात पर भी शोध कर रहा है, लेकिन कुछ बयानों के विरोध में कि IN को OR की पंक्ति में बदल दिया जाएगा, s I could say that it can also be converted to UNIONजिसे क्वेरी को ऑप्टिमाइज़ करने के लिए ORA को प्रतिस्थापित करने के लिए पुन: बनाया गया है।
जैनीस ग्रूजिस

जवाबों:


249

मुझे यह सुनिश्चित करने के लिए जानने की जरूरत है, इसलिए मैंने दोनों तरीकों को बेंचमार्क किया। मैं लगातार INउपयोग करने की तुलना में बहुत तेज पाया गया OR

उन लोगों पर विश्वास न करें जो अपनी "राय" देते हैं, विज्ञान सभी परीक्षण और सबूत के बारे में है।

मैंने 1000x का एक लूप समतुल्य प्रश्नों (संगतता के लिए, मैंने इस्तेमाल किया sql_no_cache) को चलाया :

IN: 2.34969592094s

OR: 5.83781504631

अपडेट:
(मेरे पास मूल परीक्षण के लिए स्रोत कोड नहीं है, क्योंकि यह 6 साल पहले था, हालांकि यह इस परीक्षण के समान सीमा में परिणाम देता है)

इसे जांचने के लिए कुछ नमूना कोड के अनुरोध में, यहां सबसे सरल संभव उपयोग मामला है। वाक्यविन्यास सरलता के लिए वाक्पटु का उपयोग करते हुए, कच्चे एसक्यूएल समतुल्य समान निष्पादित करता है।

$t = microtime(true); 
for($i=0; $i<10000; $i++):
$q = DB::table('users')->where('id',1)
    ->orWhere('id',2)
    ->orWhere('id',3)
    ->orWhere('id',4)
    ->orWhere('id',5)
    ->orWhere('id',6)
    ->orWhere('id',7)
    ->orWhere('id',8)
    ->orWhere('id',9)
    ->orWhere('id',10)
    ->orWhere('id',11)
    ->orWhere('id',12)
    ->orWhere('id',13)
    ->orWhere('id',14)
    ->orWhere('id',15)
    ->orWhere('id',16)
    ->orWhere('id',17)
    ->orWhere('id',18)
    ->orWhere('id',19)
    ->orWhere('id',20)->get();
endfor;
$t2 = microtime(true); 
echo $t."\n".$t2."\n".($t2-$t)."\n";

1482080514.3635
1482080517.3713
3.0078368186951

$t = microtime(true); 
for($i=0; $i<10000; $i++): 
$q = DB::table('users')->whereIn('id',[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20])->get(); 
endfor; 
$t2 = microtime(true); 
echo $t."\n".$t2."\n".($t2-$t)."\n";

1482080534.0185
1482080536.178
2.1595389842987


21
इन परीक्षणों में किन अनुक्रमों का उपयोग किया गया था?
१३:२१ पर एग्जाइकल

5
मैं भी प्रश्नों का अनुकूलन कर रहा था और यह पाया कि यह INकथन लगभग 30% तेजी से था OR
टिमो २

12
Do not believe people who give their "opinion"आप 100% सही हैं, स्टैक ओवरफ्लो दुर्भाग्य से उनमें से भरा हुआ है
elipoultorak

7
प्रदर्शन का कारण (मारियाडीबी (एक MySQL नई मुक्त शाखा) डॉक्स उद्धृत करते हुए): => यदि आपका कॉलम पूर्णांक है, तो पूर्णांकों को भी पास करें ...Returns 1 if expr is equal to any of the values in the IN list, else returns 0. If all values are constants, they are evaluated according to the type of expr and sorted. The search for the item then is done using a binary search. This means IN is very quick if the IN value list consists entirely of constants . Otherwise, type conversion takes place according to the rules described at Type Conversion, but applied to all the arguments.IN
jave.web

10
' उन लोगों पर विश्वास न करें, जो अपनी "राय" देते हैं : " उन आंकड़ों को प्राप्त करने के लिए उपयोग की जाने वाली स्क्रिप्ट, तालिकाओं और अनुक्रमितों को शामिल किए बिना प्रदर्शन के आंकड़े प्रदान करना उन्हें असाध्य बनाता है। जैसे, आंकड़े "राय" के रूप में अच्छे हैं।
मोहभंग हुआ

67

मैंने भविष्य के Googlers के लिए एक परीक्षण भी किया। लौटे परिणामों की कुल गिनती 10000 में से 7264 है

SELECT * FROM item WHERE id = 1 OR id = 2 ... id = 10000

इस क्वेरी में 0.1239सेकंड्स लगे

SELECT * FROM item WHERE id IN (1,2,3,...10000)

इस क्वेरी में 0.0433सेकंड्स लगे

IN से 3 गुना तेज है OR


15
MySQL इंजन क्या था और क्या आपने दो प्रश्नों के बीच MySQL बफ़र्स और OS फ़ाइल कैश को साफ़ किया?
dabest1

2
आपका परीक्षण एक संकीर्ण उपयोग-मामला है। क्वेरी डेटा का 72% देता है, और अनुक्रमित से लाभ की संभावना नहीं है।
१ill

मैं शर्त लगाता हूं कि अधिकांश समय क्वेरी का उपभोग कर रहा था, इसे पार्स कर रहा था, और क्वेरी की योजना बना रहा था। यह निश्चित रूप से एक विचार है: यदि आप 10k या स्टेटमेंट्स के लिए जा रहे हैं, तो आप बहुत अधिक निरर्थक पाठ के साथ इसे व्यक्त करने जा रहे हैं OR: संभव सबसे कॉम्पैक्ट अभिव्यक्ति का उपयोग करने के लिए सबसे अच्छा।
बिशप

18

स्वीकृत उत्तर इसका कारण नहीं बताता है।

नीचे उच्च प्रदर्शन MySQL, तृतीय संस्करण से उद्धृत किया गया है।

कई डेटाबेस सर्वरों में, IN () मल्टीपल या क्लॉस के लिए एक पर्यायवाची है, क्योंकि दोनों तार्किक रूप से समान हैं। MySQL में ऐसा नहीं है, जो IN () सूची में मानों को क्रमबद्ध करता है और यह देखने के लिए कि क्या सूची में कोई मान है, यह देखने के लिए एक तेज़ बाइनरी खोज का उपयोग करता है। यह सूची के आकार में O (लॉग एन) है, जबकि सूची के आकार में OR (खंड) के बराबर श्रृंखला O (n) है (यानी, बड़ी सूचियों के लिए बहुत धीमी)


विशिष्ट डेटाबेस कारण के लिए शानदार संदर्भ। अच्छा!
जोशुआ पिंटर

परफेक्ट और टू द पॉइंट
गौरव ६

16

मुझे लगता है कि बेटविन तेज हो जाएगा क्योंकि इसे में बदलना चाहिए:

Field >= 0 AND Field <= 5

यह मेरी समझ है कि IN को वैसे भी OR स्टेटमेंट के एक समूह में बदल दिया जाएगा। IN का मान उपयोग में आसानी है। (प्रत्येक कॉलम नाम को कई बार टाइप करने पर सहेजना और मौजूदा लॉजिक के साथ उपयोग करना भी आसान बना देता है - आपको AND / या पूर्ववर्तीता के बारे में चिंता करने की आवश्यकता नहीं है क्योंकि IN एक स्टेटमेंट है। OR स्टेटमेंट्स के एक समूह के साथ, आपके पास है। यह सुनिश्चित करने के लिए कि आप उन्हें एक शर्त के रूप में मूल्यांकित करते हैं, उन्हें कोष्ठक के साथ घेरें।)

आपके प्रश्न का एकमात्र वास्तविक उत्तर आपकी शख्सियत है । तब आपको पता चलेगा कि आपकी विशेष स्थिति में सबसे अच्छा क्या काम करता है।


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

"यह मेरी समझ है कि IN को वैसे भी OR कथनों के एक समूह में बदल दिया जाएगा।" आपने यह कहां पढ़ा? मुझे उम्मीद है कि इसे हेमपैप में डालकर ओ (1) लुक दिया जाएगा।
जिट्क्स

में परिवर्तित किया जा रहा है या कैसे SQLServer इसे संभालता है (या कम से कम यह किया है - अब बदल सकता है, वर्षों में इसका इस्तेमाल नहीं किया है)। मुझे ऐसा कोई सबूत नहीं मिला है जो MySQL ऐसा करता हो।
रिचर्डअटोम

4
यह उत्तर सही है, बीच में "1 <= film_id <= 5" में परिवर्तित हो गया है। अन्य दो समाधानों को एकल श्रेणी की स्थिति में नहीं बांधा गया है। मेरे पास एक ब्लॉग पोस्ट है जो यहाँ OPTIMIZER TRACE का उपयोग करके इसे प्रदर्शित करता है: tocker.ca/2015/05/25/…
Morgan Tocker

13

यह इस बात पर निर्भर करता है कि आप क्या कर रहे हैं; यह कितना विस्तृत है, डेटा प्रकार क्या है (मुझे पता है कि आपका उदाहरण एक संख्यात्मक डेटा प्रकार का उपयोग करता है, लेकिन आपका प्रश्न बहुत भिन्न डेटा प्रकारों पर भी लागू हो सकता है)।

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

मुझे यकीन है कि इसका कोई ठोस जवाब है, लेकिन यह है कि मैं कैसे, व्यावहारिक रूप से बोल रहा हूं, मेरे दिए गए प्रश्न के उत्तर का पता लगाएं।

यह कुछ मदद हो सकती है: http://forge.mysql.com/wiki/Top10SQLPerformanceTips

सादर,
फ्रैंक


2
यह चयनित उत्तर होना चाहिए।
जॉन जेड

3
लिंक बासी है - मुझे लगता है कि यह बराबर हो सकता है? wikis.oracle.com/pages/viewpage.action?pageId=27263381 (धन्यवाद ओरेकल; -पी)
ilasno

1
समकक्ष पृष्ठ पर, यह कहता है: "अनुक्रमित फ़ील्ड पर चयन करते समय IN (...) के उपयोग से बचें, यह SELV क्वेरी के प्रदर्शन को मार देगा।" - किसी भी विचार क्यों है?
जॉरिस

url की अवधि समाप्त हो गई है
स्टीव जियांग

7

मुझे लगता है कि सनसेकर के अवलोकन के बारे में एक स्पष्टीकरण यह है कि MySQL वास्तव में IN स्टेटमेंट में मूल्यों को क्रमबद्ध करता है यदि वे सभी स्थिर मूल्य हैं और द्विआधारी खोज का उपयोग कर रहे हैं, जो सादे या विकल्प से अधिक कुशल है। मुझे याद नहीं है कि मैंने कहाँ पढ़ा है, लेकिन सूरज के परिणाम का एक प्रमाण प्रतीत होता है।


4

जब आपको लगा कि यह सुरक्षित है ...

आपका क्या मूल्य है eq_range_index_dive_limit? विशेष रूप से, क्या आपके पास INखंड में कम या ज्यादा आइटम हैं ?

इसमें एक बेंचमार्क शामिल नहीं होगा, लेकिन आंतरिक कामकाज में थोड़ा सहयोग करेगा। चलिए देखते हैं कि क्या चल रहा है - ऑप्टिमाइज़र ट्रेस।

पूछताछ: SELECT * FROM canada WHERE id ...

एक साथ OR3 मूल्यों की , का पता लगाने के हिस्से की तरह दिखता है:

       "condition_processing": {
          "condition": "WHERE",
          "original_condition": "((`canada`.`id` = 296172) or (`canada`.`id` = 295093) or (`canada`.`id` = 293626))",
          "steps": [
            {
              "transformation": "equality_propagation",
              "resulting_condition": "(multiple equal(296172, `canada`.`id`) or multiple equal(295093, `canada`.`id`) or multiple equal(293626, `canada`.`id`))"
            },

...

              "analyzing_range_alternatives": {
                "range_scan_alternatives": [
                  {
                    "index": "id",
                    "ranges": [
                      "293626 <= id <= 293626",
                      "295093 <= id <= 295093",
                      "296172 <= id <= 296172"
                    ],
                    "index_dives_for_eq_ranges": true,
                    "chosen": true

...

        "refine_plan": [
          {
            "table": "`canada`",
            "pushed_index_condition": "((`canada`.`id` = 296172) or (`canada`.`id` = 295093) or (`canada`.`id` = 293626))",
            "table_condition_attached": null,
            "access_type": "range"
          }
        ]

ध्यान दें कि ICP कैसे दिया जा रहा है ORs। इसका तात्पर्य यह है कि ORइसे चालू नहीं किया गया है IN, और InnoDB का एक गुच्छा प्रदर्शन किया जाएगा= ICP के माध्यम परीक्षणों । (मुझे नहीं लगता कि यह MyISAM पर विचार करने लायक है।)

(यह पेरकोना का 5.6.22-71.0-लॉग है; idएक माध्यमिक सूचकांक है।)

अब कुछ मूल्यों के साथ IN () के लिए

eq_range_index_dive_limit= 10; 8 मान हैं।

        "condition_processing": {
          "condition": "WHERE",
          "original_condition": "(`canada`.`id` in (296172,295093,293626,295573,297148,296127,295588,295810))",
          "steps": [
            {
              "transformation": "equality_propagation",
              "resulting_condition": "(`canada`.`id` in (296172,295093,293626,295573,297148,296127,295588,295810))"
            },

...

              "analyzing_range_alternatives": {
                "range_scan_alternatives": [
                  {
                    "index": "id",
                    "ranges": [
                      "293626 <= id <= 293626",
                      "295093 <= id <= 295093",
                      "295573 <= id <= 295573",
                      "295588 <= id <= 295588",
                      "295810 <= id <= 295810",
                      "296127 <= id <= 296127",
                      "296172 <= id <= 296172",
                      "297148 <= id <= 297148"
                    ],
                    "index_dives_for_eq_ranges": true,
                    "chosen": true

...

        "refine_plan": [
          {
            "table": "`canada`",
            "pushed_index_condition": "(`canada`.`id` in (296172,295093,293626,295573,297148,296127,295588,295810))",
            "table_condition_attached": null,
            "access_type": "range"
          }
        ]

ध्यान दें कि INयह नहीं लगता है OR

एक साइड नोट: ध्यान दें कि निरंतर मानों को क्रमबद्ध किया गया था । यह दो तरह से फायदेमंद हो सकता है:

  • कम कूदने से, सभी मूल्यों को प्राप्त करने के लिए बेहतर कैशिंग, कम I / O हो सकता है।
  • यदि दो समान प्रश्न अलग-अलग कनेक्शन से आ रहे हैं, और वे लेनदेन में हैं, तो ओवरलैपिंग सूचियों के कारण गतिरोध के बजाय देरी होने की बेहतर संभावना है।

अंत में, () बहुत सारे मूल्यों के साथ

      {
        "condition_processing": {
          "condition": "WHERE",
          "original_condition": "(`canada`.`id` in (293831,292259,292881,293440,292558,295792,292293,292593,294337,295430,295034,297060,293811,295587,294651,295559,293213,295742,292605,296018,294529,296711,293919,294732,294689,295540,293000,296916,294433,297112,293815,292522,296816,293320,293232,295369,291894,293700,291839,293049,292738,294895,294473,294023,294173,293019,291976,294923,294797,296958,294075,293450,296952,297185,295351,295736,296312,294330,292717,294638,294713,297176,295896,295137,296573,292236,294966,296642,296073,295903,293057,294628,292639,293803,294470,295353,297196,291752,296118,296964,296185,295338,295956,296064,295039,297201,297136,295206,295986,292172,294803,294480,294706,296975,296604,294493,293181,292526,293354,292374,292344,293744,294165,295082,296203,291918,295211,294289,294877,293120,295387))",
          "steps": [
            {
              "transformation": "equality_propagation",
              "resulting_condition": "(`canada`.`id` in (293831,292259,292881,293440,292558,295792,292293,292593,294337,295430,295034,297060,293811,295587,294651,295559,293213,295742,292605,296018,294529,296711,293919,294732,294689,295540,293000,296916,294433,297112,293815,292522,296816,293320,293232,295369,291894,293700,291839,293049,292738,294895,294473,294023,294173,293019,291976,294923,294797,296958,294075,293450,296952,297185,295351,295736,296312,294330,292717,294638,294713,297176,295896,295137,296573,292236,294966,296642,296073,295903,293057,294628,292639,293803,294470,295353,297196,291752,296118,296964,296185,295338,295956,296064,295039,297201,297136,295206,295986,292172,294803,294480,294706,296975,296604,294493,293181,292526,293354,292374,292344,293744,294165,295082,296203,291918,295211,294289,294877,293120,295387))"
            },

...

              "analyzing_range_alternatives": {
                "range_scan_alternatives": [
                  {
                    "index": "id",
                    "ranges": [
                      "291752 <= id <= 291752",
                      "291839 <= id <= 291839",
                      ...
                      "297196 <= id <= 297196",
                      "297201 <= id <= 297201"
                    ],
                    "index_dives_for_eq_ranges": false,
                    "rows": 111,
                    "chosen": true

...

        "refine_plan": [
          {
            "table": "`canada`",
            "pushed_index_condition": "(`canada`.`id` in (293831,292259,292881,293440,292558,295792,292293,292593,294337,295430,295034,297060,293811,295587,294651,295559,293213,295742,292605,296018,294529,296711,293919,294732,294689,295540,293000,296916,294433,297112,293815,292522,296816,293320,293232,295369,291894,293700,291839,293049,292738,294895,294473,294023,294173,293019,291976,294923,294797,296958,294075,293450,296952,297185,295351,295736,296312,294330,292717,294638,294713,297176,295896,295137,296573,292236,294966,296642,296073,295903,293057,294628,292639,293803,294470,295353,297196,291752,296118,296964,296185,295338,295956,296064,295039,297201,297136,295206,295986,292172,294803,294480,294706,296975,296604,294493,293181,292526,293354,292374,292344,293744,294165,295082,296203,291918,295211,294289,294877,293120,295387))",
            "table_condition_attached": null,
            "access_type": "range"
          }
        ]

साइड नोट: मुझे ट्रेस की भारीता के कारण इसकी आवश्यकता थी:

@@global.optimizer_trace_max_mem_size = 32222;

3

या सबसे धीमा होगा। चाहे IN या BETWEEN तेज़ हो, आपके डेटा पर निर्भर करेगा, लेकिन मैं उम्मीद करूंगा कि BETWEEN सामान्य रूप से तेज़ होगा क्योंकि यह एक इंडेक्स से कुछ रेंज ले सकता है (कुछ फील को इंडेक्स किया गया है)।


3

नीचे MySQL 5.6 @SQLFiddle का उपयोग करके 6 प्रश्नों का विवरण दिया गया है

सारांश में 6 प्रश्न स्वतंत्र रूप से अनुक्रमित स्तंभों को कवर करते हैं और प्रति डेटा प्रकार 2 प्रश्नों का उपयोग किया गया था। सभी प्रश्नों के परिणामस्वरूप आईएन () या ओआरएस की परवाह किए बिना एक सूचकांक का उपयोग किया गया।

        |   ORs      |   IN()
integer | uses index | uses index
date    | uses index | uses index
varchar | uses index | uses index

मैं वास्तव में केवल उन कथनों पर बहस करना चाहता था जिनका अर्थ है कि किसी भी सूचकांक का उपयोग नहीं किया जा सकता है। यह सच नहीं है। निम्नलिखित उदाहरणों के प्रदर्शन में अनुक्रमित या 6 प्रश्नों के रूप में अनुक्रमित किया जा सकता है।

मुझे यह भी लगता है कि कई ने इस तथ्य को नजरअंदाज कर दिया है कि IN () ORs के सेट के लिए एक वाक्यविन्यास शॉर्टकट है। IN () -v- OR का उपयोग करने के बीच छोटे पैमाने पर परफ्यूमेंस अंतर में (असीम रूप से) सीमांत है।

जबकि बड़े पैमाने पर IN () निश्चित रूप से अधिक सुविधाजनक है, लेकिन यह sill तार्किक रूप से OR स्थितियों के एक सेट के बराबर है। प्रत्येक क्वेरी के लिए परिस्थिति परिवर्तन आपके टेबल पर आपके प्रश्न का परीक्षण हमेशा सर्वश्रेष्ठ होता है।

6 समझा योजनाओं का सारांश, सभी "सूचकांक स्थिति का उपयोग" (स्क्रॉल दाएं)

  Query               select_type    table    type    possible_keys      key      key_len   ref   rows   filtered           Extra          
                      ------------- --------- ------- --------------- ----------- --------- ----- ------ ---------- ----------------------- 
  Integers using OR   SIMPLE        mytable   range   aNum_idx        aNum_idx    4               10     100.00     Using index condition  
  Integers using IN   SIMPLE        mytable   range   aNum_idx        aNum_idx    4               10     100.00     Using index condition  
  Dates using OR      SIMPLE        mytable   range   aDate_idx       aDate_idx   6               7      100.00     Using index condition  
  Dates using IN      SIMPLE        mytable   range   aDate_idx       aDate_idx   6               7      100.00     Using index condition  
  Varchar using OR    SIMPLE        mytable   range   aName_idx       aName_idx   768             10     100.00     Using index condition  
  Varchar using IN    SIMPLE        mytable   range   aName_idx       aName_idx   768             10     100.00     Using index condition  

एसक्यूएल फिडल

MySQL 5.6 स्कीमा सेटअप :

CREATE TABLE `myTable` (
  `id` mediumint(8) unsigned NOT NULL auto_increment,
  `aName` varchar(255) default NULL,
  `aDate` datetime,
  `aNum`  mediumint(8),
  PRIMARY KEY (`id`)
) AUTO_INCREMENT=1;

ALTER TABLE `myTable` ADD INDEX `aName_idx` (`aName`);
ALTER TABLE `myTable` ADD INDEX `aDate_idx` (`aDate`);
ALTER TABLE `myTable` ADD INDEX `aNum_idx` (`aNum`);

INSERT INTO `myTable` (`aName`,`aDate`)
 VALUES 
 ("Daniel","2017-09-19 01:22:31")
,("Quentin","2017-06-03 01:06:45")
,("Chester","2017-06-14 17:49:36")
,("Lev","2017-08-30 06:27:59")
,("Garrett","2018-10-04 02:40:37")
,("Lane","2017-01-22 17:11:21")
,("Chaim","2017-09-20 11:13:46")
,("Kieran","2018-03-10 18:37:26")
,("Cedric","2017-05-20 16:25:10")
,("Conan","2018-07-10 06:29:39")
,("Rudyard","2017-07-14 00:04:00")
,("Chadwick","2018-08-18 08:54:08")
,("Darius","2018-10-02 06:55:56")
,("Joseph","2017-06-19 13:20:33")
,("Wayne","2017-04-02 23:20:25")
,("Hall","2017-10-13 00:17:24")
,("Craig","2016-12-04 08:15:22")
,("Keane","2018-03-12 04:21:46")
,("Russell","2017-07-14 17:21:58")
,("Seth","2018-07-25 05:51:30")
,("Cole","2018-06-09 15:32:53")
,("Donovan","2017-08-12 05:21:35")
,("Damon","2017-06-27 03:44:19")
,("Brian","2017-02-01 23:35:20")
,("Harper","2017-08-25 04:29:27")
,("Chandler","2017-09-30 23:54:06")
,("Edward","2018-07-30 12:18:07")
,("Curran","2018-05-23 09:31:53")
,("Uriel","2017-05-08 03:31:43")
,("Honorato","2018-04-07 14:57:53")
,("Griffin","2017-01-07 23:35:31")
,("Hasad","2017-05-15 05:32:41")
,("Burke","2017-07-04 01:11:19")
,("Hyatt","2017-03-14 17:12:28")
,("Brenden","2017-10-17 05:16:14")
,("Ryan","2018-10-10 08:07:55")
,("Giacomo","2018-10-06 14:21:21")
,("James","2018-02-06 02:45:59")
,("Colt","2017-10-10 08:11:26")
,("Kermit","2017-09-18 16:57:16")
,("Drake","2018-05-20 22:08:36")
,("Berk","2017-04-16 17:39:32")
,("Alan","2018-09-01 05:33:05")
,("Deacon","2017-04-20 07:03:05")
,("Omar","2018-03-02 15:04:32")
,("Thaddeus","2017-09-19 04:07:54")
,("Troy","2016-12-13 04:24:08")
,("Rogan","2017-11-02 00:03:25")
,("Grant","2017-08-21 01:45:16")
,("Walker","2016-11-26 15:54:52")
,("Clarke","2017-07-20 02:26:56")
,("Clayton","2018-08-16 05:09:29")
,("Denton","2018-08-11 05:26:05")
,("Nicholas","2018-07-19 09:29:55")
,("Hashim","2018-08-10 20:38:06")
,("Todd","2016-10-25 01:01:36")
,("Xenos","2017-05-11 22:50:35")
,("Bert","2017-06-17 18:08:21")
,("Oleg","2018-01-03 13:10:32")
,("Hall","2018-06-04 01:53:45")
,("Evan","2017-01-16 01:04:25")
,("Mohammad","2016-11-18 05:42:52")
,("Armand","2016-12-18 06:57:57")
,("Kaseem","2018-06-12 23:09:57")
,("Colin","2017-06-29 05:25:52")
,("Arthur","2016-12-29 04:38:13")
,("Xander","2016-11-14 19:35:32")
,("Dante","2016-12-01 09:01:04")
,("Zahir","2018-02-17 14:44:53")
,("Raymond","2017-03-09 05:33:06")
,("Giacomo","2017-04-17 06:12:52")
,("Fulton","2017-06-04 00:41:57")
,("Chase","2018-01-14 03:03:57")
,("William","2017-05-08 09:44:59")
,("Fuller","2017-03-31 20:35:20")
,("Jarrod","2017-02-15 02:45:29")
,("Nissim","2018-03-11 14:19:25")
,("Chester","2017-11-05 00:14:27")
,("Perry","2017-12-24 11:58:04")
,("Theodore","2017-06-26 12:34:12")
,("Mason","2017-10-02 03:53:49")
,("Brenden","2018-10-08 10:09:47")
,("Jerome","2017-11-05 20:34:25")
,("Keaton","2018-08-18 00:55:56")
,("Tiger","2017-05-21 16:59:07")
,("Benjamin","2018-04-10 14:46:36")
,("John","2018-09-05 18:53:03")
,("Jakeem","2018-10-11 00:17:38")
,("Kenyon","2017-12-18 22:19:29")
,("Ferris","2017-03-29 06:59:13")
,("Hoyt","2017-01-03 03:48:56")
,("Fitzgerald","2017-07-27 11:27:52")
,("Forrest","2017-10-05 23:14:21")
,("Jordan","2017-01-11 03:48:09")
,("Lev","2017-05-25 08:03:39")
,("Chase","2017-06-18 19:09:23")
,("Ryder","2016-12-13 12:50:50")
,("Malik","2017-11-19 15:15:55")
,("Zeph","2018-04-04 11:22:12")
,("Amala","2017-01-29 07:52:17")
;

update MyTable
set aNum = id
;

क्वेरी 1 :

select 'aNum by OR' q, mytable.*
from mytable
where aNum = 12
OR aNum = 22
OR aNum = 27
OR aNum = 32
OR aNum = 42
OR aNum = 52
OR aNum = 62
OR aNum = 65
OR aNum = 72
OR aNum = 82

परिणाम :

|          q | id |    aName |                aDate | aNum |
|------------|----|----------|----------------------|------|
| aNum by OR | 12 | Chadwick | 2018-08-18T08:54:08Z |   12 |
| aNum by OR | 22 |  Donovan | 2017-08-12T05:21:35Z |   22 |
| aNum by OR | 27 |   Edward | 2018-07-30T12:18:07Z |   27 |
| aNum by OR | 32 |    Hasad | 2017-05-15T05:32:41Z |   32 |
| aNum by OR | 42 |     Berk | 2017-04-16T17:39:32Z |   42 |
| aNum by OR | 52 |  Clayton | 2018-08-16T05:09:29Z |   52 |
| aNum by OR | 62 | Mohammad | 2016-11-18T05:42:52Z |   62 |
| aNum by OR | 65 |    Colin | 2017-06-29T05:25:52Z |   65 |
| aNum by OR | 72 |   Fulton | 2017-06-04T00:41:57Z |   72 |
| aNum by OR | 82 |  Brenden | 2018-10-08T10:09:47Z |   82 |

क्वेरी 2 :

select 'aNum by IN' q, mytable.*
from mytable
where aNum IN (
            12
          , 22
          , 27
          , 32
          , 42
          , 52
          , 62
          , 65
          , 72
          , 82
          )

परिणाम :

|          q | id |    aName |                aDate | aNum |
|------------|----|----------|----------------------|------|
| aNum by IN | 12 | Chadwick | 2018-08-18T08:54:08Z |   12 |
| aNum by IN | 22 |  Donovan | 2017-08-12T05:21:35Z |   22 |
| aNum by IN | 27 |   Edward | 2018-07-30T12:18:07Z |   27 |
| aNum by IN | 32 |    Hasad | 2017-05-15T05:32:41Z |   32 |
| aNum by IN | 42 |     Berk | 2017-04-16T17:39:32Z |   42 |
| aNum by IN | 52 |  Clayton | 2018-08-16T05:09:29Z |   52 |
| aNum by IN | 62 | Mohammad | 2016-11-18T05:42:52Z |   62 |
| aNum by IN | 65 |    Colin | 2017-06-29T05:25:52Z |   65 |
| aNum by IN | 72 |   Fulton | 2017-06-04T00:41:57Z |   72 |
| aNum by IN | 82 |  Brenden | 2018-10-08T10:09:47Z |   82 |

प्रश्न 3 :

select 'adate by OR' q, mytable.*
from mytable
where aDate= str_to_date("2017-02-15 02:45:29",'%Y-%m-%d %h:%i:%s')
OR aDate = str_to_date("2018-03-10 18:37:26",'%Y-%m-%d %h:%i:%s')
OR aDate = str_to_date("2017-05-20 16:25:10",'%Y-%m-%d %h:%i:%s')
OR aDate = str_to_date("2018-07-10 06:29:39",'%Y-%m-%d %h:%i:%s')
OR aDate = str_to_date("2017-07-14 00:04:00",'%Y-%m-%d %h:%i:%s')
OR aDate = str_to_date("2018-08-18 08:54:08",'%Y-%m-%d %h:%i:%s')
OR aDate = str_to_date("2018-10-02 06:55:56",'%Y-%m-%d %h:%i:%s')
OR aDate = str_to_date("2017-04-20 07:03:05",'%Y-%m-%d %h:%i:%s')
OR aDate = str_to_date("2018-03-02 15:04:32",'%Y-%m-%d %h:%i:%s')
OR aDate = str_to_date("2017-09-19 04:07:54",'%Y-%m-%d %h:%i:%s')
OR aDate = str_to_date("2016-12-13 04:24:08",'%Y-%m-%d %h:%i:%s')

परिणाम :

|           q | id |    aName |                aDate | aNum |
|-------------|----|----------|----------------------|------|
| adate by OR | 47 |     Troy | 2016-12-13T04:24:08Z |   47 |
| adate by OR | 76 |   Jarrod | 2017-02-15T02:45:29Z |   76 |
| adate by OR | 44 |   Deacon | 2017-04-20T07:03:05Z |   44 |
| adate by OR | 46 | Thaddeus | 2017-09-19T04:07:54Z |   46 |
| adate by OR | 10 |    Conan | 2018-07-10T06:29:39Z |   10 |
| adate by OR | 12 | Chadwick | 2018-08-18T08:54:08Z |   12 |
| adate by OR | 13 |   Darius | 2018-10-02T06:55:56Z |   13 |

प्रश्न 4 :

select 'adate by IN' q, mytable.*
from mytable
where aDate IN (
          str_to_date("2017-02-15 02:45:29",'%Y-%m-%d %h:%i:%s')
        , str_to_date("2018-03-10 18:37:26",'%Y-%m-%d %h:%i:%s')
        , str_to_date("2017-05-20 16:25:10",'%Y-%m-%d %h:%i:%s')
        , str_to_date("2018-07-10 06:29:39",'%Y-%m-%d %h:%i:%s')
        , str_to_date("2017-07-14 00:04:00",'%Y-%m-%d %h:%i:%s')
        , str_to_date("2018-08-18 08:54:08",'%Y-%m-%d %h:%i:%s')
        , str_to_date("2018-10-02 06:55:56",'%Y-%m-%d %h:%i:%s')
        , str_to_date("2017-04-20 07:03:05",'%Y-%m-%d %h:%i:%s')
        , str_to_date("2018-03-02 15:04:32",'%Y-%m-%d %h:%i:%s')
        , str_to_date("2017-09-19 04:07:54",'%Y-%m-%d %h:%i:%s')
        , str_to_date("2016-12-13 04:24:08",'%Y-%m-%d %h:%i:%s')
        )

परिणाम :

|           q | id |    aName |                aDate | aNum |
|-------------|----|----------|----------------------|------|
| adate by IN | 47 |     Troy | 2016-12-13T04:24:08Z |   47 |
| adate by IN | 76 |   Jarrod | 2017-02-15T02:45:29Z |   76 |
| adate by IN | 44 |   Deacon | 2017-04-20T07:03:05Z |   44 |
| adate by IN | 46 | Thaddeus | 2017-09-19T04:07:54Z |   46 |
| adate by IN | 10 |    Conan | 2018-07-10T06:29:39Z |   10 |
| adate by IN | 12 | Chadwick | 2018-08-18T08:54:08Z |   12 |
| adate by IN | 13 |   Darius | 2018-10-02T06:55:56Z |   13 |

क्वेरी 5 :

select 'name by  OR' q, mytable.*
from mytable
where aname = 'Alan'
OR aname = 'Brian'
OR aname = 'Chandler'
OR aname = 'Darius'
OR aname = 'Evan'
OR aname = 'Ferris'
OR aname = 'Giacomo'
OR aname = 'Hall'
OR aname = 'James'
OR aname = 'Jarrod'

परिणाम :

|           q | id |    aName |                aDate | aNum |
|-------------|----|----------|----------------------|------|
| name by  OR | 43 |     Alan | 2018-09-01T05:33:05Z |   43 |
| name by  OR | 24 |    Brian | 2017-02-01T23:35:20Z |   24 |
| name by  OR | 26 | Chandler | 2017-09-30T23:54:06Z |   26 |
| name by  OR | 13 |   Darius | 2018-10-02T06:55:56Z |   13 |
| name by  OR | 61 |     Evan | 2017-01-16T01:04:25Z |   61 |
| name by  OR | 90 |   Ferris | 2017-03-29T06:59:13Z |   90 |
| name by  OR | 37 |  Giacomo | 2018-10-06T14:21:21Z |   37 |
| name by  OR | 71 |  Giacomo | 2017-04-17T06:12:52Z |   71 |
| name by  OR | 16 |     Hall | 2017-10-13T00:17:24Z |   16 |
| name by  OR | 60 |     Hall | 2018-06-04T01:53:45Z |   60 |
| name by  OR | 38 |    James | 2018-02-06T02:45:59Z |   38 |
| name by  OR | 76 |   Jarrod | 2017-02-15T02:45:29Z |   76 |

प्रश्न 6 :

select 'name by IN' q, mytable.*
from mytable
where aname IN (
      'Alan'
     ,'Brian'
     ,'Chandler'
     , 'Darius'
     , 'Evan'
     , 'Ferris'
     , 'Giacomo'
     , 'Hall'
     , 'James'
     , 'Jarrod'
     )

परिणाम :

|          q | id |    aName |                aDate | aNum |
|------------|----|----------|----------------------|------|
| name by IN | 43 |     Alan | 2018-09-01T05:33:05Z |   43 |
| name by IN | 24 |    Brian | 2017-02-01T23:35:20Z |   24 |
| name by IN | 26 | Chandler | 2017-09-30T23:54:06Z |   26 |
| name by IN | 13 |   Darius | 2018-10-02T06:55:56Z |   13 |
| name by IN | 61 |     Evan | 2017-01-16T01:04:25Z |   61 |
| name by IN | 90 |   Ferris | 2017-03-29T06:59:13Z |   90 |
| name by IN | 37 |  Giacomo | 2018-10-06T14:21:21Z |   37 |
| name by IN | 71 |  Giacomo | 2017-04-17T06:12:52Z |   71 |
| name by IN | 16 |     Hall | 2017-10-13T00:17:24Z |   16 |
| name by IN | 60 |     Hall | 2018-06-04T01:53:45Z |   60 |
| name by IN | 38 |    James | 2018-02-06T02:45:59Z |   38 |
| name by IN | 76 |   Jarrod | 2017-02-15T02:45:29Z |   76 |

2

मुझे यकीन है कि वे समान हैं, आप निम्नलिखित करके एक परीक्षण चला सकते हैं:

500 बार "इन (1,2,3,4)" पर लूप करें और देखें कि इसमें कितना समय लगता है। "= 1 या = 2 या = 3 ..." संस्करण 500 बार पर लूप करें और देखें कि यह कितनी देर चलता है।

तुम भी एक तरह से शामिल होने की कोशिश कर सकते हैं, अगर someField एक सूचकांक है और आपकी मेज बड़ी है तो यह तेज़ हो सकता है ...

SELECT ... 
    FROM ... 
        INNER JOIN (SELECT 1 as newField UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) dt ON someFIELD =newField

मैंने अपने SQL सर्वर पर शामिल होने की विधि की कोशिश की और यह लगभग (1,2,3,4) के समान है, और वे दोनों एक अनुक्रमणिका की तलाश में परिणाम करते हैं। मुझे यकीन नहीं है कि MySQL उन्हें कैसे हैंडल करेगा।



0

जिस तरह से मैं समझता हूं कि कंपाइलर इस प्रकार के प्रश्नों का अनुकूलन करता है, उसके बारे में, इन क्लॉज का उपयोग करके कई या क्लॉज की तुलना में अधिक कुशल है। यदि आपके पास ऐसे मान हैं जहां BETWEEN खंड का उपयोग किया जा सकता है, तो वह अभी भी अधिक कुशल है।


0

मुझे पता है कि, जब तक आपके पास फ़ील्ड पर एक इंडेक्स है, तब तक BETWEEN इसका उपयोग जल्दी से एक छोर ढूंढने के लिए करेगा, फिर दूसरे पर ले जाएगा। यह सबसे कुशल है।

मैंने देखा हर एक्सप्लेन "IN (...)" और "... OR ..." को विनिमेय और समान रूप से (इन) कुशल होने के लिए दिखाता है। जिसकी आपको उम्मीद होगी, क्योंकि ऑप्टिमाइज़र के पास यह जानने का कोई तरीका नहीं है कि उनमें कोई अंतराल है या नहीं। यह अलग-अलग मूल्यों पर एक UNION ALL SELECT के बराबर है।


0

जैसा कि दूसरों द्वारा समझाया गया है, IN को क्वेरी प्रदर्शन के संबंध में OR से बेहतर चुना गया है।

OR मामलों वाली क्वेरीज़ को नीचे दिए गए मामलों में अधिक लंबे समय तक निष्पादन समय लग सकता है।

  1. निष्पादित करने के लिए यदि MySQL ऑप्टिमाइज़र किसी भी अन्य सूचकांक को कुशल (झूठे सकारात्मक मामलों के दौरान) के लिए धोखा देता है।
  2. यदि अभिलेखों की संख्या अधिक है (जैसा कि जैकब द्वारा स्पष्ट रूप से कहा गया है)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.