with as语法中,生成出的中间表如何继续走tiflash参与后续运算

【 TiDB 版本】
v5.1.2
【遇到的问题】
目前我的所有表均跑在TiFlash上,由于某个查询需要union结果,并且都会用到同一个子查询,我就使用with as语法来复用子查询

sql类似于
with ids as (xxxx)
select a,sum() 
from 
(
   (select c from m inner jion ids...)
   union
  (select n from i inner jion ids...)
)
group by ...

我发现其生成的CTE表的时候是用的TiFlash,但生成出的中间结果并不是TiFlash表,导致后续join时需要走tidb节点。

有什么办法可以一直走tiflash么?

1赞

这句没太看明白。

要不先试试这样行不行:
set session tidb_isolation_read_engines = “tiflash”

1赞

我贴一下执行计划就能理解了,可以看到生成了CTE以后,在用CTE的时候走的是sql节点不是tiflash节点来进行后续运算,导致hash agg的时候用的是sql节点的内存资源

+------------------------------------------------+--------------+----------+
| id                                             | task         | memory   |
+------------------------------------------------+--------------+----------+
| Projection_73                                  | root         | 2.06 MB  |
| └─HashAgg_74                                   | root         | 815.1 MB |
|   └─Projection_83                              | root         | 1.32 MB  |
|     └─Projection_75                            | root         | 496.2 KB |
|       └─HashJoin_77                            | root         | 8.36 MB  |
|         ├─Selection_78(Build)                  | root         | 8.23 KB  |
|         │ └─CTEFullScan_79                     | root         | 16.7 MB  |
|         └─TableReader_82(Probe)                | root         | 3.65 MB  |
|           └─Selection_81                       | cop[tiflash] | N/A      |
|             └─TableFullScan_80                 | cop[tiflash] | N/A      |
| CTE_0                                          | root         | 16.7 MB  |
| └─TableReader_64(Seed Part)                    | root         | N/A      |
|   └─ExchangeSender_63                          | cop[tiflash] | N/A      |
|     └─Projection_59                            | cop[tiflash] | N/A      |
|       └─HashAgg_60                             | cop[tiflash] | N/A      |
|         └─ExchangeReceiver_62                  | cop[tiflash] | N/A      |
|           └─ExchangeSender_61                  | cop[tiflash] | N/A      |
|             └─HashAgg_25                       | cop[tiflash] | N/A      |
|               └─Union_58                       | cop[tiflash] | N/A      |
|                 ├─Projection_68                | cop[tiflash] | N/A      |
|                 │ └─Projection_41              | cop[tiflash] | N/A      |
|                 │   └─Selection_43             | cop[tiflash] | N/A      |
|                 │     └─TableFullScan_42       | cop[tiflash] | N/A      |
|                 ├─Projection_69                | cop[tiflash] | N/A      |
|                 │ └─Projection_44              | cop[tiflash] | N/A      |
|                 │   └─Selection_46             | cop[tiflash] | N/A      |
|                 │     └─TableFullScan_45       | cop[tiflash] | N/A      |
|                 └─Projection_70                | cop[tiflash] | N/A      |
|                   └─Projection_47              | cop[tiflash] | N/A      |
|                     └─Selection_49             | cop[tiflash] | N/A      |
|                       └─TableFullScan_48       | cop[tiflash] | N/A      |
+------------------------------------------------+--------------+----------+
1赞

我觉得这种是正常的吧,CTE是一个临时中间结果集放在内存中,在tiflash中并没有副本,想丢到tiflash去做join不太可能

1赞

你的sql在TiFlash上都是走的全表扫。

1赞

额,我有点没理解,在tiflash不都是叫 TableFullScan么?

这样也就意味着想走tiflash,只能让他做三次重复的子查询了,如果with as的结果集没法作为tiflash的一部分的话。
如果走sql节点,就需要把 mem-quota-query拉的非常大

是的,我觉得目前是这样的。

不知道tiflash后续有没有这块的开发计划,可以提issue问问

期待解决办法。