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

ネストされたmysqlクエリのパフォーマンスの低下

    この質問への答えは、5.7より前のmysqlを使用しているか、5.7以降のmysqlを使用しているかによって異なります。私はあなたの質問を少し変えているかもしれませんが、うまくいけば、以下はあなたが何を求めているかを捉えています。

    SELECT * FROM Table クラスタ化インデックス(物理的な順序)を介してテーブルスキャンを実行します。主キーがない場合は、暗黙的に エンジンで利用できます。あなたが言うようにwhere節はありません。フィルタリングや別のインデックスの選択は試行されません。

    説明 出力(も参照 )は、その要約に1行を示しています。それは比較的簡単です。派生テーブルBを使用したexplain出力とパフォーマンス 5.7より前のバージョンか、5.7以降のバージョンかによって異なります。

    ドキュメントMySQL5.7の派生テーブル バージョン5.6および5.7については、これを適切に説明しています。バージョン5.6および5.7では、外部クエリに組み込まれているマテリアライズド派生テーブル出力の変更によるペナルティはありません。以前のバージョンでは、派生した一時テーブルでかなりのオーバーヘッドが発生していました。

    5.7より前のパフォーマンスペナルティをテストするのは非常に簡単です。質問の派生テーブルがパフォーマンスに与える影響を確認するには、中サイズのテーブルが必要です。次の例は、バージョン5.6の小さなテーブルにあります。

    explain 
    select qm1.title  
    from questions_mysql qm1 
    join questions_mysql qm2 
    on qm2.qid<qm1.qid 
    where qm1.qid>3333 and qm1.status='O';
    +----+-------------+-------+-------+-----------------+---------+---------+------+-------+------------------------------------------------+
    | id | select_type | table | type  | possible_keys   | key     | key_len | ref  | rows  | Extra                                          |
    +----+-------------+-------+-------+-----------------+---------+---------+------+-------+------------------------------------------------+
    |  1 | SIMPLE      | qm1   | range | PRIMARY,cactus1 | PRIMARY | 4       | NULL |  5441 | Using where                                    |
    |  1 | SIMPLE      | qm2   | ALL   | PRIMARY,cactus1 | NULL    | NULL    | NULL | 10882 | Range checked for each record (index map: 0x3) |
    +----+-------------+-------+-------+-----------------+---------+---------+------+-------+------------------------------------------------+
    
    
    explain 
    select b.title from 
    (   select qid,title from questions_mysql where qid>3333 and status='O' 
    ) b 
    join questions_mysql qm2 
    on qm2.qid<b.qid; 
    +----+-------------+-----------------+-------+-----------------+---------+---------+------+-------+----------------------------------------------------+
    | id | select_type | table           | type  | possible_keys   | key     | key_len | ref  | rows  | Extra                                              |
    +----+-------------+-----------------+-------+-----------------+---------+---------+------+-------+----------------------------------------------------+
    |  1 | PRIMARY     | qm2             | index | PRIMARY,cactus1 | cactus1 | 10      | NULL | 10882 | Using index                                        |
    |  1 | PRIMARY     | <derived2>      | ALL   | NULL            | NULL    | NULL    | NULL |  5441 | Using where; Using join buffer (Block Nested Loop) |
    |  2 | DERIVED     | questions_mysql | range | PRIMARY,cactus1 | PRIMARY | 4       | NULL |  5441 | Using where                                        |
    +----+-------------+-----------------+-------+-----------------+---------+---------+------+-------+----------------------------------------------------+
    

    注:質問を変更しましたが、5.7より前のバージョンでは、派生テーブルとオプティマイザーでのインデックスの使用の欠如が与える影響を示しています。派生テーブルは、具体化されるときにインデックスの恩恵を受けます。ただし、その後は一時テーブルとしてオーバーヘッドに耐え、インデックスを使用せずに外部クエリに組み込まれます。これはバージョン5.7には当てはまりません




    1. 四半期から期間までのMySQLグループ

    2. MySQLの2つの日付の違い

    3. Mysqlグループからの注文結果

    4. hibernateは次のシーケンス値を取得できませんでした