重要
このページは英語版のページを機械翻訳しています。原文はこちらからご覧ください。

インデックスマージを使用してステートメントを説明する

IndexMergeは、テーブルにアクセスするためにTiDBv4.0で導入されたメソッドです。このメソッドを使用すると、TiDBオプティマイザーはテーブルごとに複数のインデックスを使用し、各インデックスによって返された結果をマージできます。一部のシナリオでは、このメソッドは全表スキャンを回避することでクエリをより効率的にします。

mysql> EXPLAIN SELECT * from t where a = 1 or b = 1;
+-------------------------+----------+-----------+---------------+--------------------------------------+
| id                      | estRows  | task      | access object | operator info                        |
+-------------------------+----------+-----------+---------------+--------------------------------------+
| TableReader_7           | 8000.00  | root      |               | data:Selection_6                     |
| └─Selection_6           | 8000.00  | cop[tikv] |               | or(eq(test.t.a, 1), eq(test.t.b, 1)) |
|   └─TableFullScan_5     | 10000.00 | cop[tikv] | table:t       | keep order:false, stats:pseudo       |
+-------------------------+----------+-----------+---------------+--------------------------------------+
mysql> set @@tidb_enable_index_merge = 1;
mysql> explain select * from t use index(idx_a, idx_b) where a > 1 or b > 1;
+--------------------------------+---------+-----------+-------------------------+------------------------------------------------+
| id                             | estRows | task      | access object           | operator info                                  |
+--------------------------------+---------+-----------+-------------------------+------------------------------------------------+
| IndexMerge_16                  | 6666.67 | root      |                         |                                                |
| ├─IndexRangeScan_13(Build)     | 3333.33 | cop[tikv] | table:t, index:idx_a(a) | range:(1,+inf], keep order:false, stats:pseudo |
| ├─IndexRangeScan_14(Build)     | 3333.33 | cop[tikv] | table:t, index:idx_b(b) | range:(1,+inf], keep order:false, stats:pseudo |
| └─TableRowIDScan_15(Probe)     | 6666.67 | cop[tikv] | table:t                 | keep order:false, stats:pseudo                 |
+--------------------------------+---------+-----------+-------------------------+------------------------------------------------+

上記のクエリでは、フィルタ条件はORをコネクタとして使用するWHERE句です。 IndexMergeがないと、テーブルごとに1つのインデックスしか使用できません。 a = 1をインデックスaにプッシュダウンすることはできません。どちらもインデックスb = 1にプッシュダウンすることはできませbtに大量のデータが存在する場合、全表スキャンは非効率的です。このようなシナリオを処理するために、テーブルにアクセスするためにIndexMergeがTiDBに導入されています。

IndexMergeを使用すると、オプティマイザはテーブルごとに複数のインデックスを使用し、各インデックスによって返された結果をマージして、上の図の後者IndexMergeの実行プランを生成できます。ここで、 IndexMerge_16オペレーターには3つの子ノードがあり、そのうちIndexRangeScan_13IndexRangeScan_14は、範囲スキャンの結果に基づいて条件を満たすRowIDをすべて取得し、 TableRowIDScan_15オペレーターは、これらのRowIDに従って条件を満たすすべてのデータを正確に読み取ります。 。

IndexRangeScanなどの特定の範囲のデータに対して実行されるスキャン操作の場合、結果のTableRangeScan列には、 operator info / IndexFullScanなどの他のスキャン操作と比較したスキャン範囲に関する追加情報が含まれTableFullScan 。上記の例では、 IndexRangeScan_13演算子のrange:(1,+inf]は、演算子が1から正の無限大までデータをスキャンすることを示しています。

ノート:

  • インデックスマージ機能は、v5.4.0からデフォルトで有効になっています。つまり、 tidb_enable_index_mergeONです。

  • SQLヒントUSE_INDEX_MERGEを使用すると、 tidb_enable_index_mergeの設定に関係なく、オプティマイザにインデックスマージを適用させることができます。フィルタリング条件にプッシュダウンできない式が含まれている場合にインデックスマージを有効にするには、SQLヒントUSE_INDEX_MERGEを使用する必要があります。

  • インデックスマージは、選言標準形( orで接続された式)のみをサポートし、連言標準形( andで接続された式)をサポートしません。

  • 現在、インデックスマージはtempoarayテーブルではサポートされていません。

このページの内容