Допустим, у меня есть две таблицы в BigQuery, l
и r
. Оба имеют одинаковую структуру:
ts
TIMESTAMP
a
INTEGER
b
INTEGER
Кроме того, оба разделены по времени в поле ts
. Основное отличие состоит в том, что r
имеет несколько дублированных строк, а l
имеет только уникальные (a
, b
, ts
) кортежи.
Очевидно, что реальный вариант использования более сложный, я максимально упростил данные.
Следующий запрос обрабатывает 1.2 GB
данных.
select l.ts, l.a, l.b
from l
join r using(ts, a, b)
Если я сохраняю только одну неделю данных, потребление снижается до 48.5 MB
.
select l.ts, l.a, l.b
from l
join r using(ts, a, b)
where date(l.ts) between "2020-03-16" and "2020-03-22"
Однако, если я переключусь на левое соединение, потребление возрастет до 673.5 MB
.
select l.ts, l.a, l.b
from l
left join r using(ts, a, b)
where date(l.ts) between "2020-03-16" and "2020-03-22"
Таблицы l
и r
соответственно содержат 530.4 MB
и 652.2 MB
. При фильтрации по диапазону дат эти числа go уменьшаются до 21.3 MB
и 27.1 MB
.
. При переключении в левое соединение потребление 673.5 MB
равно 21.3 MB
+ * 1051. * (сканирование разделов l
+ полное сканирование r
).
Я не понимаю, почему мы не можем уменьшить объем данных, отсканированных в таблице r
при использовании левого соединения. Это ожидается? В таком случае, почему?
В реальном случае я должен использовать левое соединение. Обходное решение - использовать приведенный ниже запрос, который потребляет 48.5 MB
, как и ожидалось.
select l.ts, l.a, l.b
from (select * from l where ts between "2020-03-16" and "2020-03-22") l
left join (select * from r where ts between "2020-03-16" and "2020-03-22") using(ts, a, b) r
Однако для моего варианта использования (использование с таблицей) он далек от идеала.