TiFlashでサポートされるプッシュダウン計算
このドキュメントでは、 TiFlashでサポートされているプッシュダウン計算を紹介します。
プッシュダウン演算子
TiFlash は、次の演算子のプッシュダウンをサポートしています。
- TableScan: テーブルからデータを読み取ります。
- 選択: データをフィルタリングします。
- HashAgg: ハッシュ集計アルゴリズムに基づいてデータの集計を実行します。
- StreamAgg: ストリーム集計アルゴリズムに基づいてデータの集計を実行します。 SteamAgg は
GROUP BY
条件なしの集計のみをサポートします。 - TopN: TopN 計算を実行します。
- リミット: リミット計算を実行します。
- プロジェクト: 投影計算を実行します。
- HashJoin: ハッシュ結合アルゴリズムを使用して結合計算を実行しますが、次の条件が適用されます。
- オペレータはMPPモードの場合のみ押下可能です。
- サポートされている結合は、内部結合、左結合、セミ結合、アンチセミ結合、左セミ結合、およびアンチ左セミ結合です。
- 前述の結合は、等価結合と非等価結合 (デカルト結合またはヌル認識半結合) の両方をサポートしています。デカルト結合またはヌル認識セミ結合を計算する場合、シャッフル ハッシュ結合アルゴリズムの代わりにブロードキャスト アルゴリズムが使用されます。
- ウィンドウ関数 : 現在、 TiFlash は
ROW_NUMBER()
、RANK()
、DENSE_RANK()
、LEAD()
、およびLAG()
をサポートしています。
TiDB では、オペレーターはツリー構造で編成されます。オペレーターをTiFlashにプッシュダウンするには、次の前提条件をすべて満たす必要があります。
- その子オペレータはすべてTiFlashにプッシュダウンできます。
- 演算子に式が含まれている場合 (ほとんどの演算子には式が含まれています)、演算子のすべての式をTiFlashにプッシュダウンできます。
プッシュダウン式
TiFlash は、次のプッシュダウン式をサポートしています。
式のタイプ | オペレーション |
---|---|
数値関数と演算子 | + - / * % >= <= = != < > ROUND() ABS() FLOOR(int) CEIL(int) CEILING(int) SQRT() LOG() LOG2() LOG10() LN() EXP() POW() SIGN() RADIANS() DEGREES() CONV() CRC32() GREATEST(int/real) LEAST(int/real) |
論理関数と演算子 | AND 、 OR 、 NOT 、 CASE WHEN 、 IF() 、 IFNULL() 、 ISNULL() 、 IN 、 LIKE 、 ILIKE 、 COALESCE 、 IS |
ビット単位の演算 | & (ビット数)、 ` |
文字列関数 | SUBSTR() CHAR_LENGTH() REPLACE() CONCAT() CONCAT_WS() LEFT() RIGHT() ASCII() LENGTH() TRIM() LTRIM() RTRIM() POSITION() FORMAT() LOWER() UCASE() UPPER() SUBSTRING_INDEX() LPAD() RPAD() STRCMP() |
正規表現の関数と演算子 | REGEXP REGEXP_LIKE() REGEXP_INSTR() REGEXP_SUBSTR() REGEXP_REPLACE() |
日付関数 | DATE_FORMAT() TIMESTAMPDIFF() FROM_UNIXTIME() UNIX_TIMESTAMP(int) UNIX_TIMESTAMP(decimal) STR_TO_DATE(date) STR_TO_DATE(datetime) DATEDIFF() YEAR() MONTH() DAY() EXTRACT(datetime) DATE() HOUR() MICROSECOND() MINUTE() SECOND() SYSDATE() DATE_ADD/ADDDATE(datetime, int) DATE_ADD/ADDDATE(string, int/real) DATE_SUB/SUBDATE(datetime, int) DATE_SUB/SUBDATE(string, int/real) QUARTER() DAYNAME() DAYOFMONTH() DAYOFWEEK() DAYOFYEAR() LAST_DAY() MONTHNAME() TO_SECONDS() TO_DAYS() FROM_DAYS() WEEKOFYEAR() |
JSON関数 | JSON_LENGTH() -> ->> JSON_EXTRACT() |
変換関数 | CAST(int AS DOUBLE), CAST(int AS DECIMAL) 、 CAST(int AS STRING) 、 CAST(int AS TIME) 、 CAST(double AS INT) 、 CAST(double AS DECIMAL) 、 CAST(double AS STRING) 、 CAST(double AS TIME) 、 CAST(string AS INT) CAST(string AS TIME) CAST(string AS DOUBLE), CAST(string AS DECIMAL) CAST(decimal AS INT) 、 20 、 CAST(decimal AS STRING) 、 CAST(decimal AS TIME) 、 CAST(time AS INT) 、 CAST(time AS DECIMAL) 、 CAST(time AS STRING) 、 CAST(time AS REAL) |
集計関数 | MIN() MAX() SUM() COUNT() AVG() APPROX_COUNT_DISTINCT() GROUP_CONCAT() |
その他の関数 | INET_NTOA() INET_ATON() INET6_NTOA() INET6_ATON() |
制限
Bit、Set、および Geometry タイプを含む式をTiFlashにプッシュダウンすることはできません。
DATE_ADD()
、DATE_SUB()
、ADDDATE()
、およびSUBDATE()
関数は、次の間隔タイプのみをサポートします。他の間隔タイプが使用されている場合、 TiFlash はエラーを報告します。- 日
- 週
- 月
- 年
- 時間
- 分
- 2番
ROWS
またはRANGE
タイプのフレームが付いたウィンドウ関数をTiFlashにプッシュダウンすることはできません。
クエリでサポートされていないプッシュダウン計算が発生した場合、TiDB は残りの計算を完了する必要があり、これはTiFlashアクセラレーション効果に大きな影響を与える可能性があります。現在サポートされていない演算子と式は、将来のバージョンでサポートされる可能性があります。
MAX()
のような関数は、集計関数として使用される場合はプッシュダウンでサポートされますが、ウィンドウ関数としてはサポートされません。
例
このセクションでは、演算子と式をTiFlashにプッシュダウンする例をいくつか示します。
例 1: オペレーターをTiFlashにプッシュダウンする
CREATE TABLE t(id INT PRIMARY KEY, a INT);
ALTER TABLE t SET TIFLASH REPLICA 1;
EXPLAIN SELECT * FROM t LIMIT 3;
+------------------------------+---------+--------------+---------------+--------------------------------+
| id | estRows | task | access object | operator info |
+------------------------------+---------+--------------+---------------+--------------------------------+
| Limit_9 | 3.00 | root | | offset:0, count:3 |
| └─TableReader_17 | 3.00 | root | | data:ExchangeSender_16 |
| └─ExchangeSender_16 | 3.00 | mpp[tiflash] | | ExchangeType: PassThrough |
| └─Limit_15 | 3.00 | mpp[tiflash] | | offset:0, count:3 |
| └─TableFullScan_14 | 3.00 | mpp[tiflash] | table:t | keep order:false, stats:pseudo |
+------------------------------+---------+--------------+---------------+--------------------------------+
5 rows in set (0.18 sec)
前の例では、オペレーターLimit
がデータをフィルタリングするためにTiFlashにプッシュダウンされます。これにより、ネットワーク上で転送されるデータ量が減り、ネットワークのオーバーヘッドが軽減されます。これは、 Limit_15
演算子の行のtask
列のmpp[tiflash]
値によって示されます。
例 2: 式をTiFlashにプッシュダウンする
CREATE TABLE t(id INT PRIMARY KEY, a INT);
ALTER TABLE t SET TIFLASH REPLICA 1;
INSERT INTO t(id,a) VALUES (1,2),(2,4),(11,2),(12,4),(13,4),(14,7);
EXPLAIN SELECT MAX(id + a) FROM t GROUP BY a;
+------------------------------------+---------+--------------+---------------+---------------------------------------------------------------------------+
| id | estRows | task | access object | operator info |
+------------------------------------+---------+--------------+---------------+---------------------------------------------------------------------------+
| TableReader_45 | 4.80 | root | | data:ExchangeSender_44 |
| └─ExchangeSender_44 | 4.80 | mpp[tiflash] | | ExchangeType: PassThrough |
| └─Projection_39 | 4.80 | mpp[tiflash] | | Column#3 |
| └─HashAgg_37 | 4.80 | mpp[tiflash] | | group by:Column#9, funcs:max(Column#8)->Column#3 |
| └─Projection_46 | 6.00 | mpp[tiflash] | | plus(test.t.id, test.t.a)->Column#8, test.t.a |
| └─ExchangeReceiver_23 | 6.00 | mpp[tiflash] | | |
| └─ExchangeSender_22 | 6.00 | mpp[tiflash] | | ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary] |
| └─TableFullScan_21 | 6.00 | mpp[tiflash] | table:t | keep order:false, stats:pseudo |
+------------------------------------+---------+--------------+---------------+---------------------------------------------------------------------------+
8 rows in set (0.18 sec)
前の例では、事前に計算のために式id + a
がTiFlashにプッシュダウンされています。これにより、ネットワーク上で転送されるデータ量が削減され、ネットワーク送信のオーバーヘッドが削減され、全体的な計算パフォーマンスが向上します。これは、 operator
列の値がplus(test.t.id, test.t.a)
である行のtask
列の値mpp[tiflash]
によって示されます。
例 3: プッシュダウンの制限
CREATE TABLE t(id INT PRIMARY KEY, a INT);
ALTER TABLE t SET TIFLASH REPLICA 1;
INSERT INTO t(id,a) VALUES (1,2),(2,4),(11,2),(12,4),(13,4),(14,7);
EXPLAIN SELECT id FROM t WHERE TIME(now()+ a) < '12:00:00';
+-----------------------------+---------+--------------+---------------+--------------------------------------------------------------------------------------------------+
| id | estRows | task | access object | operator info |
+-----------------------------+---------+--------------+---------------+--------------------------------------------------------------------------------------------------+
| Projection_4 | 4.80 | root | | test.t.id |
| └─Selection_6 | 4.80 | root | | lt(cast(time(cast(plus(20230110083056, test.t.a), var_string(20))), var_string(10)), "12:00:00") |
| └─TableReader_11 | 6.00 | root | | data:ExchangeSender_10 |
| └─ExchangeSender_10 | 6.00 | mpp[tiflash] | | ExchangeType: PassThrough |
| └─TableFullScan_9 | 6.00 | mpp[tiflash] | table:t | keep order:false, stats:pseudo |
+-----------------------------+---------+--------------+---------------+--------------------------------------------------------------------------------------------------+
5 rows in set, 3 warnings (0.20 sec)
前の例では、 TiFlashに対してTableFullScan
のみを実行します。他の関数はroot
で計算およびフィルタリングされ、 TiFlashにはプッシュされません。
次のコマンドを実行すると、 TiFlashにプッシュダウンできない演算子と式を特定できます。
SHOW WARNINGS;
+---------+------+------------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------------------------------------------------------------------------------------------+
| Warning | 1105 | Scalar function 'time'(signature: Time, return type: time) is not supported to push down to storage layer now. |
| Warning | 1105 | Scalar function 'cast'(signature: CastDurationAsString, return type: var_string(10)) is not supported to push down to tiflash now. |
| Warning | 1105 | Scalar function 'cast'(signature: CastDurationAsString, return type: var_string(10)) is not supported to push down to tiflash now. |
+---------+------+------------------------------------------------------------------------------------------------------------------------------------+
3 rows in set (0.18 sec)
関数Time
とCast
をTiFlashにプッシュダウンできないため、前の例の式をTiFlashに完全にプッシュダウンすることはできません。
例 4: ウィンドウ関数
CREATE TABLE t(id INT PRIMARY KEY, c1 VARCHAR(100));
ALTER TABLE t SET TIFLASH REPLICA 1;
INSERT INTO t VALUES(1,"foo"),(2,"bar"),(3,"bar foo"),(10,"foo"),(20,"bar"),(30,"bar foo");
EXPLAIN SELECT id, ROW_NUMBER() OVER (PARTITION BY id > 10) FROM t;
+----------------------------------+----------+--------------+---------------+---------------------------------------------------------------------------------------------------------------+
| id | estRows | task | access object | operator info |
+----------------------------------+----------+--------------+---------------+---------------------------------------------------------------------------------------------------------------+
| TableReader_30 | 10000.00 | root | | MppVersion: 1, data:ExchangeSender_29 |
| └─ExchangeSender_29 | 10000.00 | mpp[tiflash] | | ExchangeType: PassThrough |
| └─Projection_7 | 10000.00 | mpp[tiflash] | | test.t.id, Column#5, stream_count: 4 |
| └─Window_28 | 10000.00 | mpp[tiflash] | | row_number()->Column#5 over(partition by Column#4 rows between current row and current row), stream_count: 4 |
| └─Sort_14 | 10000.00 | mpp[tiflash] | | Column#4, stream_count: 4 |
| └─ExchangeReceiver_13 | 10000.00 | mpp[tiflash] | | stream_count: 4 |
| └─ExchangeSender_12 | 10000.00 | mpp[tiflash] | | ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#4, collate: binary], stream_count: 4 |
| └─Projection_10 | 10000.00 | mpp[tiflash] | | test.t.id, gt(test.t.id, 10)->Column#4 |
| └─TableFullScan_11 | 10000.00 | mpp[tiflash] | table:t | keep order:false, stats:pseudo |
+----------------------------------+----------+--------------+---------------+---------------------------------------------------------------------------------------------------------------+
9 rows in set (0.0073 sec)
この出力では、 Window
オペレーションのtask
列の値がmpp[tiflash]
であることがわかり、 ROW_NUMBER() OVER (PARTITION BY id > 10)
オペレーションをTiFlashにプッシュダウンできることを示しています。
CREATE TABLE t(id INT PRIMARY KEY, c1 VARCHAR(100));
ALTER TABLE t SET TIFLASH REPLICA 1;
INSERT INTO t VALUES(1,"foo"),(2,"bar"),(3,"bar foo"),(10,"foo"),(20,"bar"),(30,"bar foo");
EXPLAIN SELECT id, MAX(id) OVER (PARTITION BY id > 10) FROM t;
+-----------------------------+----------+-----------+---------------+------------------------------------------------------------+
| id | estRows | task | access object | operator info |
+-----------------------------+----------+-----------+---------------+------------------------------------------------------------+
| Projection_6 | 10000.00 | root | | test.t1.id, Column#5 |
| └─Shuffle_14 | 10000.00 | root | | execution info: concurrency:5, data sources:[Projection_8] |
| └─Window_7 | 10000.00 | root | | max(test.t1.id)->Column#5 over(partition by Column#4) |
| └─Sort_13 | 10000.00 | root | | Column#4 |
| └─Projection_8 | 10000.00 | root | | test.t1.id, gt(test.t1.id, 10)->Column#4 |
| └─TableReader_10 | 10000.00 | root | | data:TableFullScan_9 |
| └─TableFullScan_9 | 10000.00 | cop[tikv] | table:t1 | keep order:false, stats:pseudo |
+-----------------------------+----------+-----------+---------------+------------------------------------------------------------+
7 rows in set (0.0010 sec)
この出力では、 Window
オペレーションのtask
列の値がroot
であることがわかります。これは、 MAX(id) OVER (PARTITION BY id > 10)
オペレーションをTiFlashにプッシュダウンできないことを示しています。これは、 MAX()
は集計関数としてのプッシュダウンのみがサポートされており、ウィンドウ関数としてはサポートされていないためです。