Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / INNER JOIN ... OR ... / 5 сообщений из 5, страница 1 из 1
13.11.2020, 15:18
    #40017957
ilejn
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
INNER JOIN ... OR ...
Приветствую уважаемое сообщество,

есть запрос

==
select * from t1 inner join t2 on t1.id=t2.id or t1.idd=t2.idd

==

исполняется над табличками по миллиону записей в каждой

==
ilejn=> \d t1
Table "public.t1"
Column | Type | Collation | Nullable | Default
--------+-------------------+-----------+----------+---------
id | integer | | |
idd | integer | | |
s | character varying | | |
Indexes:
"t1_id_ind" btree (id)
"t1_idd_ind" btree (idd)

ilejn=> \d t2
Table "public.t2"
Column | Type | Collation | Nullable | Default
--------+-------------------+-----------+----------+---------
id | integer | | |
idd | integer | | |
s | character varying | | |
Indexes:
"t2_id_ind" btree (id)
"t2_idd_ind" btree (idd)
==

с вот таким планом

==
QUERY PLAN
---------------------------------------------------------------------------------
Gather (cost=1000.00..15725182688.22 rows=1 width=40)
Workers Planned: 2
-> Nested Loop (cost=0.00..15725181688.12 rows=1 width=40)
Join Filter: ((t1.id = t2.id) OR (t1.idd = t2.idd))
-> Parallel Seq Scan on t2 (cost=0.00..23274.67 rows=416667 width=20)
-> Seq Scan on t1 (cost=0.00..22740.14 rows=1000014 width=20)
JIT:
Functions: 6
Options: Inlining true, Optimization true, Expressions true, Deforming true
==

И занимает его исполнение примерно вечность.

В резалтсете должно быть три строки.

Что делать? JOIN ... OR - это какое-то больное место для PostgreSQL, попробовать переписать запрос?

Версия 12, из ubuntu 20.10 без каких-либо настроек.
...
Рейтинг: 0 / 0
13.11.2020, 15:44
    #40017968
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
INNER JOIN ... OR ...
ilejn,

перепишите на union all из 2х join нормальных.
В таком виде как вы написали так вообще нет возможности нормально ни hash join сделать ни merge join.
Потому план странный и медленный.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
13.11.2020, 15:50
    #40017970
ilejn
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
INNER JOIN ... OR ...
Maxim Boguk,

спасибо за ответ.

На самом деле, я пытаюсь понять, как разные СУБД работают с таким запросом.
В идеальном мире можно делать хэш-джойн по двум (более чем одной) функции. Кто-нибудь так умеет? Ну или что-то продвинутое, хотя бы как вы и посоветовали, сдеать два джойна, а потом объединить?
...
Рейтинг: 0 / 0
13.11.2020, 15:55
    #40017974
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
INNER JOIN ... OR ...
ilejn
Maxim Boguk,

спасибо за ответ.

На самом деле, я пытаюсь понять, как разные СУБД работают с таким запросом.
В идеальном мире можно делать хэш-джойн по двум (более чем одной) функции. Кто-нибудь так умеет? Ну или что-то продвинутое, хотя бы как вы и посоветовали, сдеать два джойна, а потом объединить?


Это задача dba/разработчика переписывать те запросы с которыми планировщик базы не справляется в те в которые он справляется.
Слишком уж узкий-нишевый случай чтобы под него специальную (и весьма непростую) инфраструктуру городить замедляя тем самым планирование обычных запросов.
Я не знаю умеет ли такое преобразование хоть одна база на рынке (по вышеуказанным причинам).

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
16.11.2020, 17:14
    #40018991
ilejn
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
INNER JOIN ... OR ...
Чтобы не ввести кого-нибудь в заблуждение, решил уточнить, что PgSQL в принципе умеет обрабатывать такие запросы быстро.

План выглядит так

==
ilejn=> explain select * from t1 inner join t2 on t1.id=t2.id or t1.idd=t2.idd;
QUERY PLAN
--------------------------------------------------------------------------------------------------
Gather (cost=5000.93..6880570563.06 rows=34319397 width=40)
Workers Planned: 2
-> Nested Loop (cost=4000.93..6877137623.36 rows=14299749 width=40)
-> Parallel Seq Scan on t2 (cost=0.00..10536.67 rows=416667 width=20)
-> Bitmap Heap Scan on t1 (cost=4000.93..11505.03 rows=500006 width=20)
Recheck Cond: ((id = t2.id) OR (idd = t2.idd))
-> BitmapOr (cost=4000.93..4000.93 rows=500007 width=0)
-> Bitmap Index Scan on t1_id_ind (cost=0.00..3750.48 rows=500006 width=0)
Index Cond: (id = t2.id)
-> Bitmap Index Scan on t1_idd_ind (cost=0.00..0.44 rows=1 width=0)
Index Cond: (idd = t2.idd)
JIT:
Functions: 5
Options: Inlining true, Optimization true, Expressions true, Deforming true
(14 rows)
==
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / INNER JOIN ... OR ... / 5 сообщений из 5, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]