|
Некорректный индекс при использовании ORDER BY c LIMIT n
|
|||
---|---|---|---|
#18+
Есть таблица, на которой висит несколько индексов, в том числе: Код: sql 1. 2.
Селективность по первому индексу довольно хорошая, однако если в запросе присутсвует ORDER BY id LIMIT n планировщик выбирает второй индекс и запрос выполняется минуты, вместо нескольких миллисекунд. В качестве временного решения помогает следующее: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
То есть я вынес сам запрос в WITH, а сортировку и LIMIT оставил снаружи. Это помогает, однако хочется понимать причину происходящего. В рассылке нашёл https://www.postgresql.org/message-id/43A998D4.4070300@gmail.com]письмо с описанием этой проблемы, однако это было в 2005 году и хочется верить что с тех пор планировщик стал умнее. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.05.2021, 20:36 |
|
Некорректный индекс при использовании ORDER BY c LIMIT n
|
|||
---|---|---|---|
#18+
bff7755a, Вы бы планы чтоли показали сначала... планировщик вполне разумно может считать исходя из имеющейся статистики что план через второй индекс будет быстрее. Покажите план (explain analyze) для Код: sql 1.
Код: sql 1.
Код: sql 1.
Код: sql 1.
Как раз и проверим что база на счет селективностей думает себе. И скорее всего станет понятнее. PS: к таким вопросам всегда версию базы стоит прилагать. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
27.05.2021, 22:58 |
|
Некорректный индекс при использовании ORDER BY c LIMIT n
|
|||
---|---|---|---|
#18+
В планах заменил список всех столбцов на один из тех, которых нет в индексах, чтобы сократить вывод. Версию забыл, прошу прощения. Версия Код: sql 1. 2. 3. 4. 5.
Первый запрос Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Второй запрос Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
Третий запрос Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Четвёртый запрос Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
... |
|||
:
Нравится:
Не нравится:
|
|||
28.05.2021, 09:20 |
|
Некорректный индекс при использовании ORDER BY c LIMIT n
|
|||
---|---|---|---|
#18+
bff7755a, У вас все упирается в самый первый запрос (cost=0.11..13720.30 rows=7685 width=8) (actual time=0.042..0.043 rows=1 loops=1) база думает что таких строк 7685 а в реалности их одна поэтому и выбирает план перебора по id. Т.е. у расходится оценка "Селективность по первому индексу довольно хорошая" с тем что база думает. Учитывая что 9.6 база древняя как незнаю кто и будет EOL осенью то вариантов как это поправить на самом деле не много. Но попробуем. Покажите что показывает Код: sql 1. 2. 3. 4. 5.
Попробуем правильно статистику подкрутить. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
28.05.2021, 16:57 |
|
Некорректный индекс при использовании ORDER BY c LIMIT n
|
|||
---|---|---|---|
#18+
Максим, спасибо, что решили помочь. Планы запросов ниже. Запрос 1 Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
Запрос 2 Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Запрос 3 Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
Также я пробовал создать индекс с обратным порядком столбцов, т.е. (package_id, has_symbol) (т.к. селективность по package_id лучше). Он всё равно не использовался. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.05.2021, 18:25 |
|
Некорректный индекс при использовании ORDER BY c LIMIT n
|
|||
---|---|---|---|
#18+
bff7755a, Все оценки нормальные... т.е. и количество строк с t.has_symbol = 1 база корректно оценивает и количество строк с t.package_id = 6360 тоже... а вот количество строк с (t.has_symbol = 1 AND t.package_id = 6360) оценка базы отличается от реальности в 7685 раз. Отсюда и кривой план. Отсюда и вывод что данные у вас не равномерно статистически распределены... а значит нормальные планы можно только угадать. Смотрите: Код: plaintext 1. 2.
И нормально никакими стат моделями такие ситуации на 9.6 не лечатся. Вам нужна тут версия не младше 12 версии где появилось https://www.postgresql.org/docs/13/sql-createstatistics.html Currently supported kinds are ndistinct, which enables n-distinct statistics, dependencies, which enables functional dependency statistics, and mcv which enables most-common values lists. которая бы скорее всего эту проблему решило. Т.е. база ту в общем не причем... у вас распределение данных отличается от статистически равномерного слишком уж сильно. PS: а чтобы это реально быстро и всегда работало сделайте индекс по (package_id, has_symbol, t_id) или если у вас всегда в этом запросе has_symbol = 1 то (package_id, t_id) where (has_symbol = 1). Тогда базе не придется угадывать какой из 2х более менее подходящих индексов лучше. PPS: было бы интересно просто для любопытства взглянуть на seq_page_cost/random_page_cost/effective_cache_size/default_statistics_target настройки у вас в базе. уж больно чудный план для select distinct package_id у вас база выбрала с моей т.з. (особенно учитывая сильно ненулевой heap fetches). -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
28.05.2021, 19:48 |
|
Некорректный индекс при использовании ORDER BY c LIMIT n
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
... |
|||
:
Нравится:
Не нравится:
|
|||
28.05.2021, 21:25 |
|
Некорректный индекс при использовании ORDER BY c LIMIT n
|
|||
---|---|---|---|
#18+
bff7755a, Это не касается вашей проблемы но случайно show enable_seqscan; не в off стоит? При random_page_cost=2 выбор IOS вместо seq_scan+sort выглядит для меня странным (для distinct запроса). -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2021, 05:36 |
|
|
start [/forum/topic.php?fid=53&msg=40073681&tid=1994012]: |
0ms |
get settings: |
12ms |
get forum list: |
16ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
35ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
55ms |
get tp. blocked users: |
2ms |
others: | 256ms |
total: | 400ms |
0 / 0 |