#apache-spark #apache-spark-sql
#apache-spark #apache-spark-sql
Вопрос:
Я использую Spark SQL 2.4.0. У меня есть пара таблиц, как показано ниже:
Таблица CUST:
id | name | age | join_dt
-------------------------
12 | John | 25 | 2019-01-05
34 | Pete | 29 | 2019-06-25
56 | Mike | 35 | 2020-01-31
78 | Alan | 30 | 2020-02-25
Таблица ССЫЛОК:
eff_dt
------
2020-01-31
Требуется выбрать все записи, из CUST
которых join_dt
есть <=
eff_dt
в REF
таблице. Итак, для этого простого требования я составил следующий запрос:
версия #1:
select
c.id,
c.name,
c.age,
c.join_dt
from cust c
inner join ref r
on c.join_dt <= r.eff_dt;
Теперь это создает BroadcastNestedLoopJoin
в физическом плане, и, следовательно, для обработки запроса требуется много времени.
Вопрос 1:
Есть ли лучший способ реализовать эту же логику без BNLJ
индуцирования и выполнить запрос быстрее? Возможно ли облегчить BNLJ
?
Часть 2:
Теперь я разбил запрос на 2 части следующим образом:-
версия #2:
select c.id, c.name, c.age, c.join_dt
from cust c
inner join ref r
on c.join_dt = r.eff_dt --equi join
union all
select c.id, c.name, c.age, c.join_dt
from cust c
inner join ref r
on c.join_dt < r.eff_dt; --theta join
Теперь для запроса в Version#1
физический план показывает, что CUST
таблица сканируется только один раз, тогда как физический план для запроса в Version#2
указывает, что одна и та же входная таблица CUST
сканируется дважды (по одному разу для каждого из 2 запросов, объединенных с union
). Однако я с удивлением обнаружил, что это Version#2
выполняется быстрее, чем version#1
.
Вопрос 2:
Как version#2
выполняется быстрее, чем version#1
хотя version#2
сканирует таблицу дважды, в отличие от одного раза в случае version#1
, а также тот факт, что обе версии вызывают BNLJ
?
Может кто-нибудь, пожалуйста, уточнить. Пожалуйста, дайте мне знать, если требуется дополнительная информация. Спасибо.
Комментарии:
1. Сколько записей в
ref
таблице?2. будет только 1 запись
3. Возможно ли для вас собрать
ref
строку таблицы в переменную? Затем, используяfilter
, вы могли бы вообще избежать объединения.4. @Izhar Ahmed спасибо за ваш ответ. Поскольку мы используем запросы Spark SQL API, у меня нет возможности указывать эту дату в переменной. Кстати, сможете ли вы пролить свет на мой вопрос № 2, пожалуйста?