【发布时间】:2019-01-22 22:41:29
【问题描述】:
我有 2 张桌子 A 和 B,它们都是 MergeTree 和 8192 index_granularity。
当我将cross join 应用于 2 个表时。一般来说,查询喜欢
select
count(*)
from
(select * from A where ... )
cross join
(select * from B where ...)
where ...;
- 原始表:
A有314307856记录,B有909470。 - 过滤掉:
A有6599记录,B有14860。 (尽管记录差异很大,但两个过滤器都非常快)
我注意到在查询中切换A 和B 的顺序时性能存在巨大差距。
当
A cross join B:1 rows in set. Elapsed: 12.242 sec. Processed 26.72 million rows当
B cross join A:1 rows in set. Elapsed: 45.584 sec. Processed 26.72 million rows
两个订单都有pipeline
CreatingSets
Lazy
Expression
Expression
ParallelAggregating
Expression × (num_parts)
Filter
Expression
Expression
Expression
Filter
MergeTreeThread
有时候,B cross join A 有
CreatingSets
Lazy
Expression
Expression
Aggregating
Concat
Expression
Filter
Expression
Limit
Expression
Union
Limit × 7
Expression
Filter
MergeTreeThread
--> 我注意到clickhouse-server 使用这条管道会很快耗尽我的记忆。
据我所知,使用join 查询,clickhouse 将首先执行右侧的执行,然后将其放入内存然后执行左侧。就我而言,过滤掉的A 和B 绝对适合内存。
我的问题是:
为什么 2 个查询的性能差异很大? 2个表的顺序如何影响查询的性能?选择订单时的一些建议。
同一查询在多次执行中的管道可以不同吗?
更新 1: 有关我的查询的更多详细信息
SELECT
count(*)
FROM
(
SELECT
...
FROM B
WHERE (((day >= '2018-08-15') AND (day <= '2018-08-16')) AND ((timestamp >= 1534310226442) AND (timestamp <= 1534399065648))) AND (log_time <= 1534316318187)
)
CROSS JOIN
(
SELECT
...
FROM A
WHERE (((day >= '2018-08-14') AND (day <= '2018-08-16')) AND ((timestamp >= 1534223826442) AND (timestamp <= 1534399065648))) AND (log_time <= 1534316318187) AND match(..., '...')
)
WHERE position(..., ...) > 1
【问题讨论】:
-
请告诉我们
WHERE子句在做什么,因为您可能并没有真正进行交叉连接。 -
嗨。首先阅读关系数据库教科书的查询优化/实现章节。另请阅读minimal reproducible example 并采取行动。
标签: join clickhouse