복붙노트

[SQL] IN 성능 대 MYSQL OR

SQL

IN 성능 대 MYSQL OR

다음과 성능에 관해서 어떤 차이가 있는지 궁금

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 ... 

또는 코드를 최적화 같은 방법으로 컴파일러에서 SQL을 최적화 MySQL의 것인가?

편집 : 코멘트에 명시된 이유 OR의에 AND의 변경.

해결법

  1. ==============================

    1.나는 두 가지 방법을 벤치마킹 그래서 나는 확실이 알 필요가 있었다. 나는 일관되게 IN이 훨씬 더 빨리 사용 또는보다 발견.

    나는 두 가지 방법을 벤치마킹 그래서 나는 확실이 알 필요가 있었다. 나는 일관되게 IN이 훨씬 더 빨리 사용 또는보다 발견.

    그들의 "의견을"주는 사람을 믿지 마세요, 과학은 모든 테스트 및 증거에 관한 것입니다.

    나는 1000 배에 해당하는 쿼리 (일관성을 위해, 내가 SQL_NO_CACHE를 사용)의 루프를 실행 :

    IN : 2.34969592094s

    OR : 5.83781504631s

    최신 정보: (그것은 6 년 전으로이 테스트와 같은 범위의 결과를 반환하지만 나는 원래 시험에 대한 소스 코드가없는)

    이를 테스트하기 위해 몇 가지 예제 코드에 대한 요청에서, 여기에 간단한 가능한 사용 사례입니다. 구문 편의상 설득력을 사용하여, 원료 SQL 상당 동일한 실행한다.

    $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";
    
    $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";
    
  2. ==============================

    2.또한 미래 Google 직원 테스트를했다. 반환 된 결과의 총 수는 10,000의 7264 밖으로

    또한 미래 Google 직원 테스트를했다. 반환 된 결과의 총 수는 10,000의 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보다

  3. ==============================

    3.나는 그것이로 변환해야하기 때문에 사이 빠를 것이라고 생각 :

    나는 그것이로 변환해야하기 때문에 사이 빠를 것이라고 생각 :

    Field >= 0 AND Field <= 5
    

    IN 어쨌든 또는 문장의 무리로 변환됩니다 나의 이해이다. IN의 값은 사용의 용이성이다. (저장 각 열 이름을 여러 번 입력도 쉽게 기존의 논리를 사용할 수있게하는 데에 -. IN이 하나 개의 문장이기 때문에 당신이 걱정 AND / OR 우선 순위로하지 않는의 무리 또는 문장으로, 당신은 당신은 확실히 그들이 하나 개의 조건으로 평가하기 위해 괄호로 둘러싸 확인합니다.)

    귀하의 질문에 대한 유일한 대답은 쿼리를 프로필입니다. 그런 다음 당신은 당신의 특정 상황에 가장 적합한 것을 알 수 있습니다.

  4. ==============================

    4.그것은 당신이 무엇을하고 있는지에 따라 달라집니다; 얼마나 다양한 데이터 유형 (내가 아는 당신의 예는 숫자 데이터 형식을 사용하지만 문제는 또한 다른 데이터 유형의 많은에 적용 할 수있는) 어떤 범위이다.

    그것은 당신이 무엇을하고 있는지에 따라 달라집니다; 얼마나 다양한 데이터 유형 (내가 아는 당신의 예는 숫자 데이터 형식을 사용하지만 문제는 또한 다른 데이터 유형의 많은에 적용 할 수있는) 어떤 범위이다.

    이 쿼리 두 가지를 작성하려는 인스턴스이다; 실행의 차이를 알아 내기 위해 EXPLAIN 사용 후는 작업을 진행합니다.

    나는이에 대한 구체적인 응답이 확신하지만, 실질적으로 내 주어진 질문에 대한 대답 파악을 말하는 것입니다 방법이다.

    이것은 약간의 도움이 될 수 있습니다 http://forge.mysql.com/wiki/Top10SQLPerformanceTips

    문안 인사, 솔직한

  5. ==============================

    5.허용 대답은 이유를 설명하지 않습니다.

    허용 대답은 이유를 설명하지 않습니다.

    다음은 고성능 MySQL은, 제 3 판에서 인용.

  6. ==============================

    6.나는 그들이 모든 정적 값이며 일반 또는 대안보다 효율적입니다 이진 검색을 사용하는 경우 선 시커의 관찰 한 설명은 실제로 정렬 IN 문에서 값 MySQL을 생각합니다. 나는 그것을 읽었 어디 기억 할 수 없지만, 선 시커의 결과는 증거가 될 것으로 보인다.

    나는 그들이 모든 정적 값이며 일반 또는 대안보다 효율적입니다 이진 검색을 사용하는 경우 선 시커의 관찰 한 설명은 실제로 정렬 IN 문에서 값 MySQL을 생각합니다. 나는 그것을 읽었 어디 기억 할 수 없지만, 선 시커의 결과는 증거가 될 것으로 보인다.

  7. ==============================

    7.그냥 당신은 안전하다고 생각했을 때 ...

    그냥 당신은 안전하다고 생각했을 때 ...

    eq_range_index_dive_limit 당신의 가치는 무엇인가? 특히, 당신이 IN 절에서 더 많거나 더 적은 항목을해야합니까?

    이 벤치 마크 포함되지 않습니다,하지만 내부 동작에 조금 피어 있습니다. 최적화 추적 -의가에 무슨 일이 일어나고 있는지 확인하기 위해 도구를 사용하자.

    질의 : 캐나다 SELECT * FROM WHERE ID ...

    과 또는 3 개 값, 같은 추적 외모의 일부 :

           "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는 관찰 보고서 제공되는 방식합니다. 이것은 그 의미 또는로 전환되지 않으며, InnoDB는 ICP를 통해의 무리 = 테스트를 수행합니다. (난의 MyISAM을 고려 가치가있다 생각하지 않습니다.)

    (이 Percona의 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로 전환합니다.

    사이드 노트 : 상수 값이 정렬 된 공지있다. 이 두 가지 방법으로 도움이 될 수 있습니다 :

    마지막으로, 값의 많은 IN ()

          {
            "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;
    
  8. ==============================

    8.OR은 느린 것입니다. BETWEEN 여부 IN 또는 귀하의 데이터에 따라 달라집니다 빠르지 만 나는 간단한 (색인 someField 가정) 인덱스의 범위를 취할 수있는 BETWEEN 빠른 일반적으로 기대하는 것입니다.

    OR은 느린 것입니다. BETWEEN 여부 IN 또는 귀하의 데이터에 따라 달라집니다 빠르지 만 나는 간단한 (색인 someField 가정) 인덱스의 범위를 취할 수있는 BETWEEN 빠른 일반적으로 기대하는 것입니다.

  9. ==============================

    9.난 당신이 다음을 수행하여 테스트를 실행할 수 있습니다, 그들은 동일 내기 할 것이다 :

    난 당신이 다음을 수행하여 테스트를 실행할 수 있습니다, 그들은 동일 내기 할 것이다 :

    은 "의 (1,2,3,4)"500 번 이상 루프 걸리는 시간을 참조하십시오. 500 배 "= 1 = 2 = 3 ..."버전을 통해 루프가 실행 시간을보고.

    당신은 또한 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 Server에서 위의 방법을 결합하고 (1,2,3,4)에서 거의 동일하다했는데, 그들은 클러스터 된 인덱스에 모두 결과를 추구합니다. 나는 MySQL이이를 처리하는 방법을 모르겠어요.

  10. ==============================

    10.아래의 MySQL 5.6을 사용하여 6 개 쿼리의 세부 사항은 @SQLFiddle

    아래의 MySQL 5.6을 사용하여 6 개 쿼리의 세부 사항은 @SQLFiddle

    요약 6 개 질의 독립적 인덱스 항목을 포함하고 (2 개) 질의는 데이터 형식에 따라 사용 하였다. 모든 질의가 사용되고없이 IN () 또는 논리합 인덱스의 사용 결과.

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

    난 정말 그냥 인덱스가 사용되지 않을 수 또는 수단했다 정체를 폭로 문에 원했다. 이것은 사실이 아니다. 인덱스는 쿼리를 사용하여 또는 다음의 실시 예에서 디스플레이 (6 개) 질의로서 사용될 수있다.

    또한 많은 IN이 () 관찰 보고서의 집합에 대한 구문 바로 가기는 사실을 무시 것을 나에게 보인다. IN () -v-를 사용하거나 매우 (infintessinally) 한계이다 사이의 작은 규모의 perfomance 차이에서.

    큰 규모의 IN에있는 동안 () 확실히 더 편리하지만, 논리적으로 세트 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  
    

    SQL 바이올린

    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 |
    
  11. ==============================

    11.2018 : IN (...)이 빠릅니다. 그러나> = && <=이 더 빨리보다입니다.

    2018 : IN (...)이 빠릅니다. 그러나> = && <=이 더 빨리보다입니다.

    여기 내 벤치 마크입니다.

  12. ==============================

    12.내가 IN 절을 사용하여 컴파일러는 이러한 유형의 쿼리를 최적화하는 방법에 대해 이해하는 바로는 여러 OR 절보다 더 효율적이다. 당신은 BETWEEN 절은 사용할 수있는 값이있는 경우, 그 여전히 더 효율적입니다.

    내가 IN 절을 사용하여 컴파일러는 이러한 유형의 쿼리를 최적화하는 방법에 대해 이해하는 바로는 여러 OR 절보다 더 효율적이다. 당신은 BETWEEN 절은 사용할 수있는 값이있는 경우, 그 여전히 더 효율적입니다.

  13. ==============================

    13.나는만큼 당신이 필드에 인덱스가 같이 사이 빨리 다음 트래버스 다른에, 한쪽 끝을 찾기 위해 사용됩니다, 알고. 이것은 가장 효율적입니다.

    나는만큼 당신이 필드에 인덱스가 같이 사이 빨리 다음 트래버스 다른에, 한쪽 끝을 찾기 위해 사용됩니다, 알고. 이것은 가장 효율적입니다.

    모든 내가 쇼를 본 적이 EXPLAIN "IN (...)"와 "... 또는 ..."효율적인 상호 교환과 동일하게 (에서)합니다. 최적화들이 간격을 포함할지 여부를 알 수있는 방법이 없기 때문에 어떤 당신이 기대하는 것입니다. 또한 개별 값에 UNION ALL SELECT에 해당합니다.

  14. from https://stackoverflow.com/questions/782915/mysql-or-vs-in-performance by cc-by-sa and MIT license