クエリの最適化

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

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 のtidb_opt_distinct_agg_push_downシステム変数またはdistinct-agg-push-down構成項目は、個別の集計クエリを書き換えて、それらを TiKV または TiFlash コプロセッサにプッシュするかどうかを制御します。

この最適化の例として、次のクエリを取り上げます。 tidb_opt_distinct_agg_push_downはデフォルトで無効になっています。これは、集計関数が TiDBレイヤーで実行されることを意味します。値を1に設定してこの最適化を有効にした後、 count(distinct a)distinct aの部分が TiKV または TiFlash Coprocessor にプッシュされます。TiKV Coprocessor の列 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)