# `IndexLookUp`データアグリゲーターと`TableRowIDScan`オペレーター

+ **`IndexLookUp`**は`RowID`を集約し、これらの`RowID`に基づいてTiKV からデータを読み取ります
+ **`TableRowIDScan`**は`RowID`に基づいてテーブルデータをスキャンします
+ **`TableRowIDScan`**の**`handle`**は、説明テーブルの**`operator info`**カラムには表示されません
+ **`IndexLookUp`**は1回のインデックススキャン`(Build)`を使用して1つの`(Probe)`と連動して行セットを取得します
+ 適切なセカンダリインデックスを使用したり、選択リストに禁止星を付けたりすると、プランを**`IndexLookUp`**から**`IndexReader`**に改善できる可能性があります

![`smart`](IndexRangeScanAndTableRowIDScanOrder_ja_001_20240407.png)

```
tidb> EXPLAIN SELECT * FROM employees WHERE first_name='Parto';
+---------------------------+---------+-----------+---------------------------------------------------+-------------------------------------------+
| id                        | estRows | task      | access object                                     | operator info                             |
+---------------------------+---------+-----------+---------------------------------------------------+-------------------------------------------+
| IndexLookUp_10            | 236.44  | root      |                                                   |                                           |
| ├─IndexRangeScan_8(Build) | 236.44  | cop[tikv] | table:employees, index:idx_first_name(first_name) | range:["Parto","Parto"], keep order:false |
| └─~!@TableRowIDScan_9(Probe) | 236.44  | cop[tikv] | table:employees@!~                                   | keep order:false                          |
+---------------------------+---------+-----------+---------------------------------------------------+-------------------------------------------+

tidb> EXPLAIN SELECT * FROM employees WHERE first_name LIKE 'Part%';
+---------------------------+---------+-----------+---------------------------------------------------+-----------------------------------------+
| id                        | estRows | task      | access object                                     | operator info                           |
+---------------------------+---------+-----------+---------------------------------------------------+-----------------------------------------+
| IndexLookUp_10            | 4.03    | root      |                                                   |                                         |
| ├─IndexRangeScan_8(Build) | 4.03    | cop[tikv] | table:employees, index:idx_first_name(first_name) | range:["Part","Paru"), keep order:false |
| └─~!@TableRowIDScan_9(Probe) | 4.03    | cop[tikv] | table:employees@!~                                   | keep order:false                        |
+---------------------------+---------+-----------+---------------------------------------------------+-----------------------------------------+
3 rows in set (0.00 sec)
```

------------------------------------------------------------------------------
このスライドと次のスライドにある5つのクエリの例は、同じスキャン方法、`IndexRangeScan`を使用しています。これらのステートメントの`WHERE`述語はすべて、セカンダリインデックス`idx_first_name`を使用してクエリできることがわかりました。この方法は、`IndexReader`と`IndexRangeScan` 組み合わせに似ていますが、違いは、TiKV ノード上の条件を満たすインデックス値を除外した後、対応する行のキー値を取得してTiDBサーバーに送信して集計することです。これらのキー値は1つでも複数でもかまいません。

その後の操作は、`IndexReader`と`IndexRangeScan` 組み合わせとは異なります。`SELECT`句では、上記のすべてのSQL文が`SELECT *`を使用しています。つまり、すべてのカラムが選択されます。この時点で、TiDBサーバーは、TiKV ノードから返されたキーバリューを受け取ったら、戻って`employees`テーブルにクエリを実行して、キーと値のペアの対応する値を取得する必要があります。セカンダリインデックス（`idx_first_name`）のみに依存しても、インデックスキーの値`first_name`しか得られないため、セカンダリルックアップを実行してテーブルから値を取得する必要があります。インデックスから取得したキーバリューに基づいてテーブルから行を取得するこの操作は、テーブルルックアップと呼ばれます。明らかに、テーブル検索操作はインデックスにアクセスするだけでなく、テーブルにアクセスする必要があるため、パフォーマンスは少し悪く、大体3位にランクされています。

「実行計画の表示」セクションで説明した実行計画のリーディングニーモニックを覚えていますか。ニーモニックは、最初に右側の行を実行し、2つの行が同じレベルにある場合は、上の行を最初に実行することです。その時、私たちはニーモニックの前半だけを説明しました。それでは、この5つの実行計画と組み合わせて、後半について説明します。

最初の行が`IndexLookUp`で、右側に段差があることがわかります。そこで、「右の行を最初に実行する」ルールを適用して、2行目に移動します。2行目と3行目は同じレベルにあるので、ニーモニックの2番目の部分が役立ちます。「2つの行が同じレベルにある場合は、上の行を最初に実行します」。それでは、それを解釈してみましょう。最初に、2行目の`IndexRangeScan`が実行されます。この時点で、セカンダリインデックス`idx_first_name` フィルタリング条件を満たすキーバリュー（キーと値のペア）がTiKV ノードからTiDBサーバーに送信されます。次に、TiDBサーバーはこれらのキーバリューを使用してTiKV ノードに戻り、3行目の`TableRowIDScan`で表されるテーブルから対応する値を読み取ります。`TableRowIDScan`のタスクは`cop[tikv]`であることがわかります。これはTiKV ノード上で発生していることを示しています。最後に、TiKV ノードは条件を満たす値をTiDBサーバーに返し、TiDBサーバーは最初の行の操作を完了します。これをインデックスルックアップと呼びます。
