結合テーブル接続の3つのアルゴリズムのアイデア:入れ子ループ結合とインデックス付け入れ子ループ結合とブロック入れ子ループ結合とBKA

一。入れ子ループ結合

Mysqlでは、Nested-Loop Joinのアルゴリズムのアイデアが結合の最適化に使用され、Nested-Loop Joinは中国語に「ネストされたループ結合」として翻訳されています。

例:
select * from t1 inner join t2 on t1.id = t2.tid
(1)t1は外部テーブルと呼ばれ、駆動テーブルとも呼ばれます。
(2)t2は内部テーブルと呼ばれ、被駆動テーブルとも呼ばれます。

Mysqlの実装では、Nested-Loop Joinには3つの実装アルゴリズムがあります。

  • 単純な入れ子ループ結合:SNLJ、単純な入れ子ループ結合
  • インデックスのネストされたループ結合:INLJ、インデックスのネストされたループ結合
  • ブロックの入れ子ループ結合:BNLJ、キャッシュブロックの入れ子ループ結合

結合アルゴリズムを選択する場合、優先順位があり、理論的には、INLJ、BNLJを使用するかどうかを決定するために優先順位が付けられます。
インデックスネストループ結合>ブロックネストループ結合>単純ネストループ結合

二。シンプルな入れ子ループ

  1. 単純なネストされたループ接続は、実際には単純で失礼なネストされたループです。table1に10,000データがあり、table2に10,000データがある場合、データ比較の数= 10,000 * 1兆= 10億回、このクエリ効率非常に遅くなります。
  2. したがって、Mysqlは引き続き最適化を行い、次に、Index Nested-LoopJoinとBlock Nested-Loop Joinの2つのNLJアルゴリズムを導出します。結合クエリを実行すると、mysqlは状況に応じて結合クエリの2つのタイプのいずれかを選択します。

3. Nested-LoopJoinにインデックスを付ける(内部テーブルデータの一致数を減らす)

  1. インデックスネストループ接続は、インデックスに基づいて接続するためのアルゴリズムです。インデックスは内部テーブルに基づいています。内部テーブルの各レコードとの比較を避けるために、外部テーブルの一致条件を通じて内部テーブルインデックスに直接一致します。インデックスクエリは、内部テーブルへの一致数を減らし、結合のパフォーマンスを大幅に向上させます。

元の一致数=外部テーブルの行数*内部テーブルの行数
最適化された一致数=外部テーブルの行数*内部テーブルのインデックスの高さ

  1. 使用シナリオ:インデックスNested-LoopJoinを使用して接続できるのは、内部テーブルの結合列にインデックスがある場合のみです。
  2. インデックスが使用されているため、インデックスが補助インデックスであり、返されたデータに内部テーブルの他のデータも含まれている場合、内部テーブルに戻ってデータをクエリし、いくつかのIO操作が追加されます。

4.ブロックの入れ子ループ結合(内部テーブルデータのサイクル数を減らす)

  1. キャッシュブロックのネストされたループ接続は、一度に複数のデータをキャッシュし、クエリに参加している列を結合バッファーにキャッシュしてから、結合バッファーのデータを内部テーブルのデータとバッチで照合し、それにより内部ループの数を減らします(内部テーブルを一度トラバースすると、結合バッファー内の外部テーブルデータをバッチで照合できます)。
  2. Index Nested-Loop Joinを使用しない場合は、デフォルトでBlock Nested-Loop Joinが使用されます。
  3. 結合バッファとは何ですか?
    (1)結合バッファーは、結合列のみではなく、クエリに参加しているすべての列をキャッシュします。
    (2)join_buffer_sizeのキャッシュサイズを調整でき
    ます(3)join_buffer_size のデフォルト値は256Kで、MySQLバージョン5.1.22より前のjoin_buffer_sizeの最大値は4G-1です。64ビットオペレーティングシステムでは、4Gより大きなバージョンに適用できます。バッファスペースを結合します。
    (4)Block Nested-Loop Joinアルゴリズムを使用するには、optimizer_switch設定block_nested_loopのオプティマイザ管理構成を有効にする必要があります。これはデフォルトで有効になっています。

五.BKA

     バッチキーアクセス結合アルゴリズムの作業手順は次のとおりです。

1)外部表の関連する列を結合バッファーに入れます。

2)キー(インデックスキー値)をバッチでマルチレンジ読み取り(MRR)インターフェイスに送信します。

3)マルチレンジ読み取り(MRR)は、受信したキーを対応するROWIDに従ってソートし、データを読み取ります。

 

4)結果セットをクライアントに返します。

6.参加速度を最適化する方法

  1. 小さな結果セットを使用して大きな結果セットを駆動し、外側のループのデータ量を削減します。
    小さな結果セットと大きな結果セットで接続された列がすべてインデックス列である場合、mysqlは小さな結果セットを使用して、内部的に接続されているときに大きな結果セットを駆動することも選択します。インデックスクエリのコストは比較的固定されているため、現時点では、外部ループが少ないほど、結合速度が速くなります。
  2. 一致条件のインデックスを増やす:INLJを使用して内部テーブルのサイクル数を減らすように努力する
  3. 結合バッファサイズのサイズを増やします。BNLJを使用する場合、一度にキャッシュされるデータが多いほど、外部テーブルのサイクル数が少なくなります。
  4. 不要なフィールドクエリを減らす:
    (1)BNLJを使用すると、フィールドが少なくなり、結合バッファーにキャッシュされるデータが多くなり、外部テーブルのサイクルが少なくなります;
    (2)INLJを使用する場合、テーブルクエリに戻る必要はありません。つまり、カバリングインデックスを使用すると、速度を向上させることができる場合があります。(未検証、単なる推論)

おすすめ

転載: blog.csdn.net/qq_42000661/article/details/108578997