パーティションを使用してステートメントを説明する

EXPLAINステートメントは、クエリを実行するために TiDB がアクセスする必要があるパーティションを表示します。 パーティションの整理のため、表示されるパーティションは、多くの場合、パーティション全体のサブセットのみです。 このドキュメントでは、一般的なパーティション テーブルの最適化の一部と、 EXPLAINの出力の解釈方法について説明します。

このドキュメントで使用されているサンプル データ:

CREATE TABLE t1 ( id BIGINT NOT NULL auto_increment, d date NOT NULL, pad1 BLOB, pad2 BLOB, pad3 BLOB, PRIMARY KEY (id,d) ) PARTITION BY RANGE (YEAR(d)) ( PARTITION p2016 VALUES LESS THAN (2017), PARTITION p2017 VALUES LESS THAN (2018), PARTITION p2018 VALUES LESS THAN (2019), PARTITION p2019 VALUES LESS THAN (2020), PARTITION pmax VALUES LESS THAN MAXVALUE ); INSERT INTO t1 (d, pad1, pad2, pad3) VALUES ('2016-01-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2016-06-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2016-09-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2017-01-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2017-06-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2017-09-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2018-01-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2018-06-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2018-09-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2019-01-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2019-06-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2019-09-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2020-01-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2020-06-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)), ('2020-09-01', RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024)); INSERT INTO t1 SELECT NULL, a.d, RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000; INSERT INTO t1 SELECT NULL, a.d, RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000; INSERT INTO t1 SELECT NULL, a.d, RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000; INSERT INTO t1 SELECT NULL, a.d, RANDOM_BYTES(1024), RANDOM_BYTES(1024), RANDOM_BYTES(1024) FROM t1 a JOIN t1 b JOIN t1 c LIMIT 10000; SELECT SLEEP(1); ANALYZE TABLE t1;

次の例は、新しく作成されたパーティションテーブルに対するステートメントを示しています。

EXPLAIN SELECT COUNT(*) FROM t1 WHERE d = '2017-06-01';
+------------------------------+---------+-----------+---------------------------+-------------------------------------------+ | id | estRows | task | access object | operator info | +------------------------------+---------+-----------+---------------------------+-------------------------------------------+ | StreamAgg_21 | 1.00 | root | | funcs:count(Column#8)->Column#6 | | └─TableReader_22 | 1.00 | root | | data:StreamAgg_10 | | └─StreamAgg_10 | 1.00 | cop[tikv] | | funcs:count(1)->Column#8 | | └─Selection_20 | 8.87 | cop[tikv] | | eq(test.t1.d, 2017-06-01 00:00:00.000000) | | └─TableFullScan_19 | 8870.00 | cop[tikv] | table:t1, partition:p2017 | keep order:false | +------------------------------+---------+-----------+---------------------------+-------------------------------------------+ 5 rows in set (0.01 sec)

最も内側の( └─TableFullScan_19 )演算子から始めてルート演算子( StreamAgg_21 )に向かって逆方向に作業します。

  • TiDBは、アクセスする必要があるパーティションが1つだけ( p2017 )であることを正常に識別しました。これはaccess objectに記載されています。
  • パーティション自体は演算子└─TableFullScan_19でスキャンされ、次に└─Selection_20適用されて、開始日が2017-06-01 00:00:00.000000の行がフィルター処理されました。
  • └─Selection_20に一致する行は、 count関数をネイティブに理解するコプロセッサでストリーム集約されます。
  • 次に、各コプロセッサ要求は TiDB 内の└─TableReader_22に 1 行を送り返し、それがStreamAgg_21でストリーム集約され、1 行がクライアントに返されます。

次の例では、パーティション プルーニングによってパーティションが削除されません。

EXPLAIN SELECT COUNT(*) FROM t1 WHERE YEAR(d) = 2017;
+------------------------------------+----------+-----------+---------------------------+----------------------------------+ | id | estRows | task | access object | operator info | +------------------------------------+----------+-----------+---------------------------+----------------------------------+ | HashAgg_20 | 1.00 | root | | funcs:count(Column#7)->Column#6 | | └─PartitionUnion_21 | 5.00 | root | | | | ├─StreamAgg_36 | 1.00 | root | | funcs:count(Column#9)->Column#7 | | │ └─TableReader_37 | 1.00 | root | | data:StreamAgg_25 | | │ └─StreamAgg_25 | 1.00 | cop[tikv] | | funcs:count(1)->Column#9 | | │ └─Selection_35 | 6000.00 | cop[tikv] | | eq(year(test.t1.d), 2017) | | │ └─TableFullScan_34 | 7500.00 | cop[tikv] | table:t1, partition:p2016 | keep order:false | | ├─StreamAgg_55 | 1.00 | root | | funcs:count(Column#11)->Column#7 | | │ └─TableReader_56 | 1.00 | root | | data:StreamAgg_44 | | │ └─StreamAgg_44 | 1.00 | cop[tikv] | | funcs:count(1)->Column#11 | | │ └─Selection_54 | 14192.00 | cop[tikv] | | eq(year(test.t1.d), 2017) | | │ └─TableFullScan_53 | 17740.00 | cop[tikv] | table:t1, partition:p2017 | keep order:false | | ├─StreamAgg_74 | 1.00 | root | | funcs:count(Column#13)->Column#7 | | │ └─TableReader_75 | 1.00 | root | | data:StreamAgg_63 | | │ └─StreamAgg_63 | 1.00 | cop[tikv] | | funcs:count(1)->Column#13 | | │ └─Selection_73 | 3977.60 | cop[tikv] | | eq(year(test.t1.d), 2017) | | │ └─TableFullScan_72 | 4972.00 | cop[tikv] | table:t1, partition:p2018 | keep order:false | | ├─StreamAgg_93 | 1.00 | root | | funcs:count(Column#15)->Column#7 | | │ └─TableReader_94 | 1.00 | root | | data:StreamAgg_82 | | │ └─StreamAgg_82 | 1.00 | cop[tikv] | | funcs:count(1)->Column#15 | | │ └─Selection_92 | 20361.60 | cop[tikv] | | eq(year(test.t1.d), 2017) | | │ └─TableFullScan_91 | 25452.00 | cop[tikv] | table:t1, partition:p2019 | keep order:false | | └─StreamAgg_112 | 1.00 | root | | funcs:count(Column#17)->Column#7 | | └─TableReader_113 | 1.00 | root | | data:StreamAgg_101 | | └─StreamAgg_101 | 1.00 | cop[tikv] | | funcs:count(1)->Column#17 | | └─Selection_111 | 8892.80 | cop[tikv] | | eq(year(test.t1.d), 2017) | | └─TableFullScan_110 | 11116.00 | cop[tikv] | table:t1, partition:pmax | keep order:false | +------------------------------------+----------+-----------+---------------------------+----------------------------------+ 27 rows in set (0.00 sec)

上記の出力から:

  • TiDB は、すべてのパーティション(p2016..pMax)にアクセスする必要があると考えています。これは、述語YEAR(d) = 2017非検索可能と見なされるためです。この問題は TiDB に固有のものではありません。
  • 各パーティションがスキャンされると、 Selection演算子によって 2017 年と一致しない行が除外されます。
  • 各パーティションでストリーム集計が実行され、一致する行数がカウントされます。
  • 演算子└─PartitionUnion_21は、各パーティションにアクセスした結果を結合します。

このページは役に立ちましたか?