powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
22 сообщений из 22, страница 1 из 1
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39687764
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
SELECT dog.id, dog.summ, dog.signed
FROM dogovora dog
LEFT JOIN leads le ON (dog.peid = le.peid AND le.cnt = 1)
,LATERAL (SELECT utm_placement_type FROM utms WHERE peid = le.peid)
--LEFT JOIN utms ON utms.peid = le.id AND utms.pent = 2 -- 3я ступень
LIMIT 25;

-- так 10675ms на первый запрос и 82ms на остальные
-- а так 440ms и 2.3ms:
SELECT dog.id, dog.summ, dog.signed
FROM dogovora dog
LEFT JOIN leads le ON (dog.peid = le.peid AND le.cnt = 1)
--,LATERAL (SELECT utm_placement_type FROM utms WHERE peid = le.peid)
LEFT JOIN utms ON utms.peid = le.id AND utms.pent = 2 -- 3я ступень
LIMIT 25;


-- план 1 -------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.70..310.42 rows=25 width=20) (actual time=5.674..82.103 rows=4 loops=1)
   ->  Nested Loop  (cost=0.70..26809.59 rows=2164 width=20) (actual time=5.673..82.099 rows=4 loops=1)
         ->  Nested Loop Left Join  (cost=0.42..24566.60 rows=6891 width=24) (actual time=0.062..68.949 rows=6633 loops=1)
               ->  Seq Scan on dogovora dog  (cost=0.00..170.33 rows=6633 width=24) (actual time=0.028..2.451 rows=6633 loops=1)
               ->  Index Scan using leads_peid_pent_idx on leads le  (cost=0.42..3.67 rows=1 width=4) (actual time=0.008..0.009 rows=1 loops=6633)
                     Index Cond: (dog.peid = peid)
                     Filter: (cnt = 1)
                     Rows Removed by Filter: 0
         ->  Index Only Scan using utms_peid_pent_idx on utms  (cost=0.29..0.32 rows=1 width=4) (actual time=0.001..0.001 rows=0 loops=6633)
               Index Cond: (peid = le.peid)
               Heap Fetches: 0
 Planning time: 1.894 ms
 Execution time: 82.312 ms

-- план 2 ------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.70..97.72 rows=25 width=20) (actual time=0.054..0.297 rows=25 loops=1)
   ->  Nested Loop Left Join  (cost=0.70..26742.19 rows=6891 width=20) (actual time=0.050..0.289 rows=25 loops=1)
         ->  Seq Scan on dogovora dog  (cost=0.00..170.33 rows=6633 width=24) (actual time=0.018..0.022 rows=25 loops=1)
         ->  Nested Loop Left Join  (cost=0.70..4.00 rows=1 width=4) (actual time=0.010..0.010 rows=0 loops=25)
               ->  Index Scan using leads_peid_pent_idx on leads le  (cost=0.42..3.67 rows=1 width=12) (actual time=0.008..0.008 rows=0 loops=25)
                     Index Cond: (dog.peid = peid)
                     Filter: (cnt = 1)
                     Rows Removed by Filter: 0
               ->  Index Only Scan using utms_peid_pent_idx on utms  (cost=0.29..0.32 rows=1 width=4) (actual time=0.008..0.008 rows=0 loops=4)
                     Index Cond: ((peid = le.id) AND (pent = 2))
                     Heap Fetches: 0
 Planning time: 1.677 ms
 Execution time: 0.487 ms



я в нём пока не очень разобрался
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39687770
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудух,

Запросы разные, таблицы участвую разные.
При чем тут вообще LATERAL?
Тоже самое переписать на LEFT JOIN - будут сравнимые цифры и скорость.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39687781
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk,

а как тогда правильно задействовать тут LATERAL, сразу после FROM tbl_name его писать?

LEFT JOIN во 2м запросе
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39687782
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в смысле разные таблицы, вот же:
--,LATERAL (SELECT utm_placement_type FROM utms WHERE peid = le.peid)
LEFT JOIN utms ON utms.peid = le.id AND utms.pent = 2 -- 3я ступень
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39687785
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудух,

а куда вы AND utms.pent = 2 из lateral потеряли то?
И главное зачем вам в данном случае вообще lateral нужен то????

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39687788
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, потерялся pent, ну с ним стало 60ms... всё-равно далеко

а нужен, чтобы его понять )) я пытаюсь разобраться, как именно он работает
можете показать правильный пример из этого варианта?
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688084
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудух,

работает планировщик а не лейтерал.
лейтералом вы ограничиваете (если умеете) свободу планирования


и вы сравниваете несравниваемое. вам тогда иннер джойн нужно сравнивать
или писать "лефт джойн лейтерал (....) он труе" , например


и никакого секрета нет. работает как кореллированный запрос т.е. нестед лупом, если оптимизатор не решит захешджойниться. с дополнительным фильтром по типу иннера.
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688251
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwqи вы сравниваете несравниваемое. вам тогда иннер джойн нужно сравнивать
или писать "лефт джойн лейтерал (....) он труе" , например
так вот этот момент мне и непонятен
почему именно INNER или LEFT JOIN LATERAL ... ON true?
я мог бы написать FROM foo, LATERAL (и тут же юзать данные из foo)
но я не могу после LEFT JOIN так написать и юзать данные из LEFT JOIN ?
а ведь эти данные встают в селекте рядом с данными из foo
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688281
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудух,

не понял, чо неясно.

у рукожопов из оракла был неявный лейтерал в конструкции "тейбл".
обычно с пайплайн--ф-ями пользовался.

позднее кто-то сообразил, что лейтерал это особый отдельный случай.
и обставил его отдельной конструкцией языка.
ясной и однозначной.


запятая перед лейтералом, если стоит, переводится как "кросс джойн"
когда вам кросс не нужен -- делаете его лефтом он труе
всё предельно ясно и понятно

а не куча ора-кала
где куда не плюнь -- везде рыбу заворачивали.
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688355
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а, запятая = CROSS JOIN
Код: sql
1.
2.
3.
4.
5.
6.
SELECT dog.id, dog.summ, dog.signed
FROM dogovora dog
LEFT JOIN leads le ON (dog.peid = le.peid AND le.cnt = 1)
,LATERAL (SELECT utm_placement_type FROM utms WHERE peid = le.peid)
--LEFT JOIN utms ON utms.peid = le.id AND utms.pent = 2 -- 3я ступень
LIMIT 25;


т.е. у меня вместо запятой будет CROSS JOIN LATERAL
но вообще я пытался изобразить что-то такое:
Код: sql
1.
2.
3.
4.
SELECT p1.id, p2.id, v1, v2
FROM polygons p1, polygons p2,
    LATERAL vertices(p1.poly) v1,
    LATERAL vertices(p2.poly) v2



ну и он таки работает
и результаты вроде даже те же самые
только медленно...
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688359
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудухпочему именно INNER или LEFT JOIN LATERAL ... ON true?
я мог бы написать FROM foo, LATERAL (и тут же юзать данные из foo)
но я не могу после LEFT JOIN так написать и юзать данные из LEFT JOIN ?
Таки посмотрите синтаксис SQL в части FROM выражения: https://www.postgresql.org/docs/current/static/queries-table-expressions.html#QUERIES-FROM
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688362
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудухну и он таки работает
и результаты вроде даже те же самые
только медленно...

ещё раз по буквам, запрос с лейтералом НЕ эквивалентен (для ёптимайзира) запросу с лефт джойном.
лейтерал надо сравнивать по скорости с ИННЕР ,б, джойном.(одни и те же затраты на фильтрацию пересечения)


а запрос с лефт джойном надо сравнивать с запросом с тем же лефт джойном перед лейтералом. если все буквы выписать верно -- они будут формально эквивалентны.

и потом уже строить умозаключения о медленностях и быстринах.
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688368
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ок, вроде прояснилось, всем спасибо
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688406
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq…
работает как кореллированный запрос т.е. нестед лупом, если оптимизатор не решит захешджойниться. с дополнительным фильтром по типу иннера.
LATERAL только вложенными циклами работает. Можно как хинт пользовать…
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688424
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудухок, вроде прояснилось, всем спасибо
в общем вот такой LATERAL сделал, как надо было:
Код: sql
1.
LEFT JOIN LATERAL (SELECT podacha, odobrenie, raschet FROM dog_bank db WHERE dog.id = db.peid ORDER BY db.peid LIMIT 1) db ON true
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688425
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
мне нужно было, чтобы эти 3 колонки были доступны в основном запросе через подзапрос, где можно было бы LIMIT 1 сделать, потому что иначе дубли шли с LEFT JOIN dog_bank
правильно сделал?
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688426
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну кроме того, что ордер не на ту колонку сделал ))
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688605
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vyegorovqwwq…
работает как кореллированный запрос т.е. нестед лупом, если оптимизатор не решит захешджойниться. с дополнительным фильтром по типу иннера.
LATERAL только вложенными циклами работает. Можно как хинт пользовать…

тоже когда-то так же думал

но без лимита , хотя бы лимит 1000000000 -- не гарантированно, помнится
но спорить не буду -- давно не практиковал
если захотите прочекать -- берите таблички которые уверенно хешджойнятся при иннере.
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688806
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

LATERAL реализуется через параметризованные пути (paths). И вот что про них пишут в исходниках:
Код: plaintext
1.
2.
3.
4.
…
This path is still marked as being parameterized by A.  When we attempt to
join {B C} to A to form the complete join tree, such a path can only be
used as the inner side of a nestloop join: it will be ignored for other
possible join types.

Любой LATERAL подзапрос параметризуется по отношению к предыдущим таблицам на которые он ссылается, и таким образом он может быть только внутри NL-а.

Можно почитать README, в этом месте в частности: https://github.com/postgres/postgres/blob/master/src/backend/optimizer/README#L769
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688851
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vyegorov,

Код: sql
1.
2.
3.
4.
5.
SELECT *
FROM stats.iterations i
,lateral (select * from stats.classes  c where i.class_id = c.class_id --limit 100000000
) c
;



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
Hash Join  (cost=1.83..383510.21 rows=13152142 width=532)'
  Output: i.it_id, i.id, i.class_id, c.class_id, c.descr
  Hash Cond: (i.class_id = c.class_id)'
  ->  Seq Scan on stats.iterations i  (cost=0.00..202666.42 rows=13152142 width=12)'
        Output: i.it_id, i.id, i.class_id
  ->  Hash  (cost=1.37..1.37 rows=37 width=520)'
        Output: c.class_id, c.descr
        ->  Seq Scan on stats.classes c  (cost=0.00..1.37 rows=37 width=520)'
              Output: c.class_id, c.descr





вероятно я что-то не так понимаю в этом вот случае
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688863
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

Этот запрос трансформируется в более простой:
Код: sql
1.
SELECT * FROM stats.iterations i, stats.classes c where i.class_id = c.class_id;
...
Рейтинг: 0 / 0
от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
    #39688881
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vyegorovqwwq,

Этот запрос трансформируется в более простой:
Код: sql
1.
SELECT * FROM stats.iterations i, stats.classes c where i.class_id = c.class_id;


об том и речь.
и только "лимит миллиард" эту возможность трансформации снимает.

т.е. "лейтерал работает как хинт" -- неверное утверждение.
об чом и речь.
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / от чего LATERAL в 40 раз медленнее, чем LEFT JOIN ?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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