为什么在 SQL (Snowflake) 连接中使用 "or" 会使查询变慢?
Why does using "or" in SQL (Snowflake) joins make queries much slower?
我有两个表:
trips,列 user_id 和 bike_id
experiment_exposures,列 subject_type 和 subject_id
subject_type
可以是 User
或 Bike
而 subject_id
对应于 user_id
或 bike_id
.
前两个查询都比较快,它们花费的时间大致相同:
select count(*)
from trips
join experiment_exposures e1 on e1.subject_type = 'User' and e1.subject_id = trips.user_id
join experiment_exposures e2 on e2.subject_type = 'Bike' and e2.subject_id = trips.bike_id;
和
select count(*)
from trips
join (select * from experiment_exposures where subject_type = 'User') e1 on e1.subject_id = trips.user_id
join (select * from experiment_exposures where subject_type = 'Bike') e2 on e2.subject_id = trips.bike_id;
但是,这个查询至少慢了 100 倍:
select count(*)
from trips
join experiment_exposures e
on (e.subject_type = 'User' and e.subject_id = trips.user_id)
or (e.subject_type = 'Bike' and e.subject_id = trips.bike_id);
为什么会有这么大的差异?第一个和第三个查询不是基本相同吗?直觉上,我希望第三个查询更快,因为只有 1 个连接。
第三个查询不一样!它 returns 额外的 行 当有匹配时,而不是额外的 列 .
在你的情况下,count()
甚至都不一样。
举个小例子:
user_id bike_id
1 1
1 2
ee_id subject_type subject_id
1 bike 1
2 bike 2
3 user 1
你的前两个连接产生一个中间 table 像这样:
user_id bike_id ee_id_user ee_id2_bike
1 1 3 1
1 2 3 2
第二个returns:
user_id bike_id ee_id subject_id
1 1 3 user
1 2 1 bike
1 1 3 user
1 2 2 bike
因此结果大不相同
不过,您的问题是关于性能的。这是相关的,但是 non-equality 联接通常比 equi-joins 效率低得多。当没有相应的等式时,这适用于 ON
子句中的 OR
和 IN
(以及其他不等式)。
我有两个表:
trips,列 user_id 和 bike_id
experiment_exposures,列 subject_type 和 subject_id
subject_type
可以是 User
或 Bike
而 subject_id
对应于 user_id
或 bike_id
.
前两个查询都比较快,它们花费的时间大致相同:
select count(*)
from trips
join experiment_exposures e1 on e1.subject_type = 'User' and e1.subject_id = trips.user_id
join experiment_exposures e2 on e2.subject_type = 'Bike' and e2.subject_id = trips.bike_id;
和
select count(*)
from trips
join (select * from experiment_exposures where subject_type = 'User') e1 on e1.subject_id = trips.user_id
join (select * from experiment_exposures where subject_type = 'Bike') e2 on e2.subject_id = trips.bike_id;
但是,这个查询至少慢了 100 倍:
select count(*)
from trips
join experiment_exposures e
on (e.subject_type = 'User' and e.subject_id = trips.user_id)
or (e.subject_type = 'Bike' and e.subject_id = trips.bike_id);
为什么会有这么大的差异?第一个和第三个查询不是基本相同吗?直觉上,我希望第三个查询更快,因为只有 1 个连接。
第三个查询不一样!它 returns 额外的 行 当有匹配时,而不是额外的 列 .
在你的情况下,count()
甚至都不一样。
举个小例子:
user_id bike_id
1 1
1 2
ee_id subject_type subject_id
1 bike 1
2 bike 2
3 user 1
你的前两个连接产生一个中间 table 像这样:
user_id bike_id ee_id_user ee_id2_bike
1 1 3 1
1 2 3 2
第二个returns:
user_id bike_id ee_id subject_id
1 1 3 user
1 2 1 bike
1 1 3 user
1 2 2 bike
因此结果大不相同
不过,您的问题是关于性能的。这是相关的,但是 non-equality 联接通常比 equi-joins 效率低得多。当没有相应的等式时,这适用于 ON
子句中的 OR
和 IN
(以及其他不等式)。