为什么在SQL(Snowflake)联接中使用“或”会使查询变慢得多?

时间:2019-05-14 11:34:00

标签: sql snowflake-datawarehouse

我有两个表:

行程,列为user_id和bike_id

experiment_exposures ,带有subject_type和subject_id列

subject_type可以是UserBike,而subject_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个联接。

1 个答案:

答案 0 :(得分:2)

第三个查询是不同的!如果存在匹配项,它将返回其他,而不是其他

在您的情况下,count()甚至都不一样。

只是一个小例子:

user_id   bike_id
  1          1
  1          2

ee_id   subject_type  subject_id
  1        bike           1
  2        bike           2
  3        user           1

您的前两个联接产生一个中间表,如下所示:

user_id   bike_id    ee_id_user    ee_id2_bike
  1          1          3              1
  1          2          3              2

第二个返回:

user_id   bike_id    ee_id    subject_id
  1          1          3         user
  1          2          1         bike
  1          1          3         user
  1          2          2         bike

因此结果完全不同。

不过,您的问题是关于性能的。这是相关的,但非等分联接的效率通常比等联接低得多。当没有相应的等式时,这适用于OR子句中的INON(以及其他不等式)。