#sql #amazon-web-services #amazon-athena #presto #in-clause
Вопрос:
У меня есть следующий запрос:
select *
from Table1
where NUMid in (select NUMid
from Table2
where email = 'xyz@gmail.com')
Мое намерение состоит в том, чтобы получить список всех нумидов из таблицы 2, имеющих значение электронной почты, равное xyz@gmail.com и используйте этот список нумидов для запроса из таблицы 1.
В presto запрос сначала выполняет внешний запрос. Есть ли способ запустить и сохранить результат внутреннего запроса, а затем использовать его во внешнем запросе в presto?
Комментарии:
1. В большинстве версий SQL вы бы индексировали
Table2
так, чтобы приведенный выше поиск подзапроса выполнялся очень быстро. Но Presto не поддерживает регулярные индексы, поэтому я не знаю, что здесь можно сделать.2. Странно, так как внутренний запрос значительно упростил бы внешний запрос! Вы обеспокоены тем, что это занимает много времени? Интересно, будет ли это работать более эффективно, если сделать это через
JOIN
?
Ответ №1:
Оптимизатор может делать все, что ему заблагорассудится. В этом случае он должен выполнить внутренний запрос один раз, а затем, по сути, выполнить JOIN
операцию (технически «полу-соединение»).
Во многих базах данных exists
наличие соответствующих индексов решает проблему производительности.
Если вы хотите убедиться, что подзапрос оценивается только один раз, вы можете переместить его в ON
предложение. Правильный эквивалентный запрос выглядит следующим образом:
select t1.*
from Table1 t1 join
(select distinct t2.NUMid
from Table2 t2
where t2.email = 'xyz@gmail.com'
) t2
on t1.NUMid = t2.NUMid;
Важно select distinct
, чтобы join
код был эквивалентен in
коду. Однако, если вы знаете, что дубликатов нет, это более разговорно написано без подзапроса:
select t1.*
from Table1 t1 join
Table2 t2
on t1.NUMid = t2.NUMid
where t2.email = 'xyz@gmail.com'
Ответ №2:
Presto и Trino (ранее известные как PrestoSQL) выполняют этот запрос как операцию «полусоединения»: он создает индекс в памяти со строками, поступающими из внутреннего запроса, и проверяет строки внешнего запроса на соответствие этому индексу. Если значение присутствует, то выводится строка из внешнего запроса, в противном случае она отфильтровывается.
В последних версиях Trino появилась функция «динамическая фильтрация», которая позволяет механизму запросов динамически фильтровать и удалять данные для внешнего запроса в источнике на основе информации, динамически полученной из внутреннего запроса. Вы можете прочитать больше об этом в этих сообщениях в блоге: