sql >> データベース >  >> RDS >> Mysql

Mysqlはオフセットのあるクエリでインデックスを使用しません

    次のことを考慮してください。ここでは、220万行をテーブルに強制します

    スキーマ

    create table tbl
    (   id int auto_increment primary key,
        thing int not null
    )engine=MyISAM;
    
    insert tbl(thing) values (7),(7),(7),(7),(7),(7),(7),(7),(7),(7),(7),(7),(7),(7),(7),(7),(7);
    
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    insert into tbl(thing) select thing from tbl;
    

    カウント

    select count(*) as theCount,max(id) as theMax,min(id) as thMin from tbl;
    +----------+---------+-------+
    | theCount | theMax  | thMin |
    +----------+---------+-------+
    |  2228224 | 2228224 |     1 |
    +----------+---------+-------+
    

    クエリA(あなたの、派生テーブルを使用)

    explain 
    SELECT *  
    FROM `tbl` 
    JOIN 
    (SELECT id FROM `tbl` ORDER BY id LIMIT 1000000, 100) as b 
    on `b`.`id` = `tbl`.`id`;
    +----+-------------+------------+--------+---------------+---------+---------+------+---------+-------------+
    | id | select_type | table      | type   | possible_keys | key     | key_len | ref  | rows    | Extra       |
    +----+-------------+------------+--------+---------------+---------+---------+------+---------+-------------+
    |  1 | PRIMARY     | <derived2> | ALL    | NULL          | NULL    | NULL    | NULL | 1000100 | NULL        |
    |  1 | PRIMARY     | tbl        | eq_ref | PRIMARY       | PRIMARY | 4       | b.id |       1 | NULL        |
    |  2 | DERIVED     | tbl        | index  | NULL          | PRIMARY | 4       | NULL | 2228224 | Using index |
    +----+-------------+------------+--------+---------------+---------+---------+------+---------+-------------+
    

    クエリB(派生テーブルではない)

    explain 
    SELECT t1.*  
    FROM tbl t1 
    JOIN tbl t2 
    on t2.id = t1.id 
    where t2.id>1000000 
    limit 100 
    +----+-------------+-------+--------+---------------+---------+---------+--------------------+---------+--------------------------+
    | id | select_type | table | type   | possible_keys | key     | key_len | ref                | rows    | Extra                    |
    +----+-------------+-------+--------+---------------+---------+---------+--------------------+---------+--------------------------+
    |  1 | SIMPLE      | t2    | range  | PRIMARY       | PRIMARY | 4       | NULL               | 1195836 | Using where; Using index |
    |  1 | SIMPLE      | t1    | eq_ref | PRIMARY       | PRIMARY | 4       | so_gibberish.t2.id |       1 | NULL                     |
    +----+-------------+-------+--------+---------------+---------+---------+--------------------+---------+--------------------------+
    

    Explainの使用に慣れていない人のために 、こちら で行った記事をご覧ください




    1. プロシージャ/関数を使用せずにMySQLでループを実行できますか?

    2. Java JDBCはsetFetchSizeを無視しますか?

    3. PostgreSQL-別のセル値に従ってデフォルトのセル値を設定します

    4. Flot、html、PHP、およびMySqlクエリを使用して複数のグラフを描画します