When joining to a very small/empty table why MySQL makes a full scan in spite of I'm using “LIMIT”?

后端 未结 3 1323
栀梦
栀梦 2021-01-16 15:54

EDIT: I removed the GROUP BY clause from the example queries but the same problem shows \"When I join table x to an empty/1 row table y MySQL makes a full table

3条回答
  •  醉梦人生
    2021-01-16 16:11

    After some tests it turns out that if the second table(user_school_mm) has some data MySQL will not make full table scan on the first table, and if the second table(country) has no data/very little data (1 or 2 records) MySQL will do a full table scan. Why this happens? I don't know.

    How to reproduce

    1- Create a schema like this

    CREATE TABLE `event` (
       `ev_id` int(11) NOT NULL AUTO_INCREMENT,
       `ev_note` varchar(255) DEFAULT NULL,
       PRIMARY KEY (`ev_id`)
     ) ENGINE=InnoDB;
    
    CREATE TABLE `table1` (
       `id` int(11) NOT NULL AUTO_INCREMENT,
       `name` varchar(45) DEFAULT NULL,   
       PRIMARY KEY (`id`)
     ) ENGINE=InnoDB ;
    
    CREATE TABLE `table2` (
       `id` int(11) NOT NULL AUTO_INCREMENT,
       `name` varchar(45) DEFAULT NULL,   
       PRIMARY KEY (`id`)
     ) ENGINE=InnoDB ;
    

    2- insert in the main table (event in this case) some data (I filled it with 35601000 rows)

    3- leave table1 empty and insert 15 rows in table2

    insert into table2 (name) values 
    ('fooBar'),('fooBar'),('fooBar'),('fooBar'),('fooBar'),
    ('fooBar'),('fooBar'),('fooBar'),('fooBar'),('fooBar'),
    ('fooBar'),('fooBar'),('fooBar'),('fooBar'),('fooBar');
    

    4- now join the main table with table2 and retest the same query with table1

    Query 1 (Fast)

    select * 
    from 
        event left join 
        table2 on event.ev_id = table2.id
    order by event.ev_id
    limit 2;
    -- executed in 300 milliseconds measured by the client
    

    Explain

    +---+-----------+--------+------+----------------+--------+---------+------------------+------+--------+
    |id |select_type|table   | type | possible_keys  | key    | key_len | ref              | rows | Extra  |
    +---+-----------+--------+------+----------------+--------+---------+------------------+------+--------+
    |1  |SIMPLE     |event   |index |                |PRIMARY |4        |                  | 2    |        |
    |1  |SIMPLE     |table2  |eq_ref|PRIMARY         |PRIMARY |4        |tests.event.ev_id | 1    |        |
    +---+-----------+--------+------+----------------+--------+---------+------------------+------+--------+
    

    Query 2 (Slow)

    select * 
    from 
        event left join 
        table1 on event.ev_id = table1.id
    order by event.ev_id
    limit 2;
    -- executed in 79 seconds measured by the client
    

    Explain

    +---+-----------+--------+------+----------------+--------+---------+-------+---------+---------------------------------------------------+
    |id |select_type|table   | type | possible_keys  | key    | key_len | ref   | rows    | Extra                                             |
    +---+-----------+--------+------+----------------+--------+---------+-------+---------+---------------------------------------------------+
    |1  |SIMPLE     |event   |ALL   |                |        |         |       |33506704 | Using temporary; Using filesort                   |
    |1  |SIMPLE     |table1  |ALL   |PRIMARY         |        |         |       |1        | Using where; Using join buffer (Block Nested Loop)|
    +---+-----------+--------+------+----------------+--------+---------+-------+---------+---------------------------------------------------+
    

    MySQL version is 5.6.38

提交回复
热议问题