クエリの最適化

このドキュメントでは、TiDB クエリ オプティマイザーのdistinct最適化 (集計関数のSELECT DISTINCTDISTINCTを含む) を紹介します。

SELECTステートメントのDISTINCT修飾子

DISTINCT修飾子は、結果セットからの重複行の削除を指定します。たとえば、 SELECT DISTINCTGROUP BYに変換されます。

mysql> explain SELECT DISTINCT a from t;
+--------------------------+---------+-----------+---------------+-------------------------------------------------------+
| id                       | estRows | task      | access object | operator info                                         |
+--------------------------+---------+-----------+---------------+-------------------------------------------------------+
| HashAgg_6                | 2.40    | root      |               | group by:test.t.a, funcs:firstrow(test.t.a)->test.t.a |
| └─TableReader_11         | 3.00    | root      |               | data:TableFullScan_10                                 |
|   └─TableFullScan_10     | 3.00    | cop[tikv] | table:t       | keep order:false, stats:pseudo                        |
+--------------------------+---------+-----------+---------------+-------------------------------------------------------+
3 rows in set (0.00 sec)

集計関数のDISTINCTオプション

通常、 DISTINCTオプションを指定した集約関数は、シングルスレッド実行モデルの TiDBレイヤーで実行されます。

TiDB のdistinct-agg-push-down構成項目は、個別の集計クエリを書き換えて TiKV またはTiFlashコプロセッサーにプッシュするかどうかを制御します。

TiDB のtidb_opt_distinct_agg_push_downシステム変数は、個別の集計クエリを書き換えて TiKV またはTiFlashコプロセッサーにプッシュするかどうかを制御します。

この最適化の例として、次のクエリを取り上げます。 tidb_opt_distinct_agg_push_downはデフォルトで無効になっています。これは、集計関数がTiDBレイヤーで実行されることを意味します。値を1に設定してこの最適化を有効にすると、 count(distinct a)distinct a部分が TiKV またはTiFlashコプロセッサーにプッシュされます。TiKVコプロセッサーの列 a で重複した値を削除するための HashAgg_5 があります。これにより、TiDBレイヤーのHashAgg_8の計算オーバーヘッドが削減される可能性があります。

mysql> desc select count(distinct a) from test.t;
+-------------------------+----------+-----------+---------------+------------------------------------------+
| id                      | estRows  | task      | access object | operator info                            |
+-------------------------+----------+-----------+---------------+------------------------------------------+
| StreamAgg_6             | 1.00     | root      |               | funcs:count(distinct test.t.a)->Column#4 |
| └─TableReader_10        | 10000.00 | root      |               | data:TableFullScan_9                     |
|   └─TableFullScan_9     | 10000.00 | cop[tikv] | table:t       | keep order:false, stats:pseudo           |
+-------------------------+----------+-----------+---------------+------------------------------------------+
3 rows in set (0.01 sec)

mysql> set session tidb_opt_distinct_agg_push_down = 1;
Query OK, 0 rows affected (0.00 sec)

mysql> desc select count(distinct a) from test.t;
+---------------------------+----------+-----------+---------------+------------------------------------------+
| id                        | estRows  | task      | access object | operator info                            |
+---------------------------+----------+-----------+---------------+------------------------------------------+
| HashAgg_8                 | 1.00     | root      |               | funcs:count(distinct test.t.a)->Column#3 |
| └─TableReader_9           | 1.00     | root      |               | data:HashAgg_5                           |
|   └─HashAgg_5             | 1.00     | cop[tikv] |               | group by:test.t.a,                       |
|     └─TableFullScan_7     | 10000.00 | cop[tikv] | table:t       | keep order:false, stats:pseudo           |
+---------------------------+----------+-----------+---------------+------------------------------------------+
4 rows in set (0.00 sec)
Playground
新規
登録なしで TiDB の機能をワンストップでインタラクティブに体験できます。
製品
TiDB Cloud
TiDB
価格
PoC お問い合わせ
エコシステム
TiKV
TiFlash
OSS Insight
© 2023 PingCAP. All Rights Reserved.