|
INNER JOIN ... OR ...
|
|||
---|---|---|---|
#18+
Приветствую уважаемое сообщество, есть запрос == 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 без каких-либо настроек. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.11.2020, 15:18 |
|
INNER JOIN ... OR ...
|
|||
---|---|---|---|
#18+
ilejn, перепишите на union all из 2х join нормальных. В таком виде как вы написали так вообще нет возможности нормально ни hash join сделать ни merge join. Потому план странный и медленный. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
13.11.2020, 15:44 |
|
INNER JOIN ... OR ...
|
|||
---|---|---|---|
#18+
Maxim Boguk, спасибо за ответ. На самом деле, я пытаюсь понять, как разные СУБД работают с таким запросом. В идеальном мире можно делать хэш-джойн по двум (более чем одной) функции. Кто-нибудь так умеет? Ну или что-то продвинутое, хотя бы как вы и посоветовали, сдеать два джойна, а потом объединить? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.11.2020, 15:50 |
|
INNER JOIN ... OR ...
|
|||
---|---|---|---|
#18+
ilejn Maxim Boguk, спасибо за ответ. На самом деле, я пытаюсь понять, как разные СУБД работают с таким запросом. В идеальном мире можно делать хэш-джойн по двум (более чем одной) функции. Кто-нибудь так умеет? Ну или что-то продвинутое, хотя бы как вы и посоветовали, сдеать два джойна, а потом объединить? Это задача dba/разработчика переписывать те запросы с которыми планировщик базы не справляется в те в которые он справляется. Слишком уж узкий-нишевый случай чтобы под него специальную (и весьма непростую) инфраструктуру городить замедляя тем самым планирование обычных запросов. Я не знаю умеет ли такое преобразование хоть одна база на рынке (по вышеуказанным причинам). -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
13.11.2020, 15:55 |
|
INNER JOIN ... OR ...
|
|||
---|---|---|---|
#18+
Чтобы не ввести кого-нибудь в заблуждение, решил уточнить, что 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) == ... |
|||
:
Нравится:
Не нравится:
|
|||
16.11.2020, 17:14 |
|
|
start [/forum/topic.php?fid=53&msg=40018991&tid=1994374]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
153ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
55ms |
get tp. blocked users: |
2ms |
others: | 293ms |
total: | 551ms |
0 / 0 |