|
быстрый Nested Loop и медленный Merge join
|
|||
---|---|---|---|
#18+
Есть иерархическая таблица Document, есть простой рекурсивный запрос, получаем записи вниз по иерархии, поле иерархии Hier Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
На одной БД планировщик использует Nested Loop запрос выполняется быстро Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
На другой БД с примерно теми же данными используется Merge Join и запрос выполняется очень долго и много ресурсов использует Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
В обеих базах есть индекс по полю Hier, пробовал выполнить vacuum analyze, reindex, обновить статистику для планировщика - ничего не помогает. Как решить проблему на второй базе, заставить планировщик использовался Nested Loop? ... |
|||
:
Нравится:
Не нравится:
|
|||
31.01.2021, 02:10 |
|
быстрый Nested Loop и медленный Merge join
|
|||
---|---|---|---|
#18+
polin11, Разница в оценке " -> Index Scan using "iDocument-Hier" on "Document" s (cost=0.43..27.52 rows=9 width=272) (actual time=0.194..0.203 rows=4 loops=1)" " Index Cond: ("Hier" = 4634473)" vs " -> Index Scan using "iDocument-Hier" on "Document" s (cost=0.56..1610.97 rows=581 width=277) (actual time=7.373..9.128 rows=4 loops=1)" " Index Cond: ("Hier" = 939969)" при фактически одинаковых результатах... а покажите вот какие вещи explain analyze select from Document" WHERE "Hier" = 4634473; с первой базы и explain analyze select from "Document" WHERE "Hier" = 939969; со второй базы... далее с ОБОИХ баз результаты explain analyze select from "Document"; и explain analyze select distinct "Hier" from "Document"; по этим итогам можно будет понять насколько "с примерно теми же данными" и главное как это поправить. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
31.01.2021, 05:27 |
|
быстрый Nested Loop и медленный Merge join
|
|||
---|---|---|---|
#18+
Maxim Boguk, для первой БД базы с nested loop Код: sql 1. 2.
Код: sql 1. 2. 3. 4. 5.
Код: sql 1.
Код: sql 1. 2. 3. 4.
Код: sql 1.
Код: sql 1. 2. 3. 4. 5.
для проблемной БД с Merge Join Код: sql 1. 2.
Код: sql 1. 2. 3. 4. 5.
Код: sql 1.
Код: sql 1. 2. 3.
Код: sql 1.
Код: sql 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
31.01.2021, 13:09 |
|
быстрый Nested Loop и медленный Merge join
|
|||
---|---|---|---|
#18+
polin11 Код: sql 1.
Код: sql 1.
Уже здесь два порядка разницы видно. Можно попробовать два варианта: 1. Расширить расчет статистик со 100 (по умолчанию) до 1000 уникальных значений поля "Hier". Тогда планировщик сможет точнее предсказывать количество строк при выборке по "iDocument-Hier". Код: sql 1. 2.
2. Создать расширенную статистику по взаимосвязи предок-потомок в таблице "Document". Тогда планировщик скорее уйдет во вложенный цикл, так как будет знать, сколько же в среднем потомков у одного предка. Код: sql 1. 2.
... |
|||
:
Нравится:
Не нравится:
|
|||
31.01.2021, 15:21 |
|
быстрый Nested Loop и медленный Merge join
|
|||
---|---|---|---|
#18+
polin11, hm а вы уверены что 1)у баз одинаковый default_statistics_target (show default_statistics_target ;) ? 2)если ответ да одинаковый то не нет ли измененной статистики по "Document"."Hier" на первой базе где проблемы нет (через alter table set statistics) 3)если тоже нет то не стоит ли ручной n_distinct в первой базе для колонки "Document"."Hier" Проблема у вас в разнице вот тут вот принципиальной первая база Код: plaintext
вторая база Код: plaintext
отсюда и план плывет... вам интересно разобраться что и почему? или интересно быстро починить... если быстро починить то просто на проблемной базе сделать или Код: plaintext 1.
или что более правильно Код: plaintext 1.
после чего проверить что explain analyze select distinct "Hier" from "Document"; стал адекватные цифры выдавать и аналогично что план запроса исправился. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
31.01.2021, 16:27 |
|
быстрый Nested Loop и медленный Merge join
|
|||
---|---|---|---|
#18+
Maxim Boguk, расширенные статистики мне нередко помогали в иерархических запросах. Особенно, когда иерархий много, но узких, как у ТС (17 записей на выходе). У него же на обоих базах расширенная статистика просится, так как в плане на три порядка больше записей в результате запроса, чем по факту. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.01.2021, 16:40 |
|
быстрый Nested Loop и медленный Merge join
|
|||
---|---|---|---|
#18+
ptr128 Maxim Boguk, расширенные статистики мне нередко помогали в иерархических запросах. Особенно, когда иерархий много, но узких, как у ТС (17 записей на выходе). У него же на обоих базах расширенная статистика просится, так как в плане на три порядка больше записей в результате запроса, чем по факту. единственное зачем в данном случае нужен увеличенный statistics target - чтобы база могла более точно количество уникальных значений подсчитать (потому что явно значения с 4 вхождениями в гистограмму most common values не попадут никогда)... а это намного проще и эффективнее через n_distinct базе сказать явным образом. почему плохо бездумно расширенная статистика: 1)при увеличении stat target в 10 раз - пропорционально в 10 раз становится тяжелее analyze (что не всегда приемлемо и может быть больно при pg_upgrade) 2)замедление времени планирования (во много раз тоже) при использовании более широкой статистики (я уже много раз получал снижение нагрузки на базу в пару раз поставив default_statistics_target=10 вместо 100 и подняв статистику в тех локальных местах где после этого ломались планы... потому что на быстрых запросах время планирования часто >> времени исполнения а prepared запросов естественно нет из за повсеместного использования pgbouncer и такого же повсеместного нежелания использовать хранимки так что приходится не скорость выполнения оптимизировать при 50.000+ rps а скорость планирования). а вот простановка n_distinct в 90% случаев является вполне рабочей заменой расширенной статистики для планировщика. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
31.01.2021, 18:02 |
|
быстрый Nested Loop и медленный Merge join
|
|||
---|---|---|---|
#18+
Maxim Boguk почему плохо бездумно расширенная статистика: 1)при увеличении stat target в 10 раз Какая связь между расширенными статистиками и увеличением stat target? ... |
|||
:
Нравится:
Не нравится:
|
|||
31.01.2021, 19:09 |
|
быстрый Nested Loop и медленный Merge join
|
|||
---|---|---|---|
#18+
ptr128 Maxim Boguk почему плохо бездумно расширенная статистика: 1)при увеличении stat target в 10 раз Какая связь между расширенными статистиками и увеличением stat target? И чем это плохо? ptr128 Создать расширенную статистику по взаимосвязи предок-потомок в таблице "Document". Тогда планировщик скорее уйдет во вложенный цикл, так как будет знать, сколько же в среднем потомков у одного предка. Код: sql 1. 2.
... |
|||
:
Нравится:
Не нравится:
|
|||
31.01.2021, 19:13 |
|
быстрый Nested Loop и медленный Merge join
|
|||
---|---|---|---|
#18+
ptr128 Maxim Boguk почему плохо бездумно расширенная статистика: 1)при увеличении stat target в 10 раз Какая связь между расширенными статистиками и увеличением stat target? я понял что под расширенными статистиками вы имеете в виду stats target. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
31.01.2021, 19:58 |
|
быстрый Nested Loop и медленный Merge join
|
|||
---|---|---|---|
#18+
ptr128 ptr128 пропущено... Какая связь между расширенными статистиками и увеличением stat target? И чем это плохо? ptr128 Создать расширенную статистику по взаимосвязи предок-потомок в таблице "Document". Тогда планировщик скорее уйдет во вложенный цикл, так как будет знать, сколько же в среднем потомков у одного предка. Код: sql 1. 2.
я вот пытаюсь понять как именно планировщик будет эту стату использовать потому что вещей типа "сколько же в среднем потомков у одного предка" в расширенной статистике нет... так есть только "Currently supported kinds are ndistinct, which enables n-distinct statistics, dependencies, which enables functional dependency statistics" и из них это никак не выводится даже теоретически. для эксперимента можно сделать конечно но я подозревают что ошибка в оценке Merge Join (cost=480.01..1189895.76 rows=12426393 width=277) (actual time=27057.258..27059.673 rows=6 loops=2)" тут никак не исправится. вреда не будет но и пользы в этом конкретном запросе скорее всего тоже. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
31.01.2021, 20:07 |
|
|
start [/forum/topic.php?fid=53&fpage=16&tid=1994223]: |
0ms |
get settings: |
10ms |
get forum list: |
11ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
39ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
70ms |
get tp. blocked users: |
1ms |
others: | 45ms |
total: | 193ms |
0 / 0 |