为什么在 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 可以是 UserBikesubject_id 对应于 user_idbike_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 子句中的 ORIN(以及其他不等式)。