Почему использование "или" в соединениях SQL (Snowflake) делает запросы намного медленнее? - PullRequest
0 голосов
/ 14 мая 2019

У меня есть две таблицы:

поездки , с колонками user_id и bike_id

эксперимент_экспозиции , с колонками 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 объединение.

1 Ответ

2 голосов
/ 14 мая 2019

Третий запрос отличается! Он возвращает дополнительные строки при совпадении, а не дополнительные столбцы .

В вашем случае 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 и IN в предложении ON (а также к другим неравенствам), когда нет соответствующего равенства.

...