|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Есть 2 таблицы(material, materialdata)): Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Выполняю такой запрос: Код: sql 1. 2. 3. 4.
По идее должен выполниться быстро, так как на tag_id и detection_datetime висят индексы. Но в реальности происходит следующее: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
16 секунд длится запрос. Меня смущает Bitmap Heap Scan on san_materialdata u0 (cost=4652.60..630118.97 rows=248779 width=4). Это нормально? Можно ли как нибудь оптимизировать? 16 секунд это еще не самый долгий запрос. Есть похожие запросы по несколько минут. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 15:03 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
а чего не join? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 15:50 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
SharuPoNemnoguа чего не join? джойны чуть побыстрее работают, но не всегда: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 15:54 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, это вот с такого запроса explain ? Код: plsql 1. 2. 3. 4. 5. 6. 7.
... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 16:15 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
SharuPoNemnogumaxxstorm, это вот с такого запроса explain ? Код: plsql 1. 2. 3. 4. 5. 6. 7.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 16:16 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
К тому же, если джойн делать, то надо distinct или group by, потому что material_id в materialdata могут повторяться. Поэтому эксплейн еще вырастет ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 16:20 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
а если составной индекс на material_id, tag_id? и еще попробовать вариант с exists, вместо join ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 16:27 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
автор(cost=0.00..4591.23 rows=248888 width=0) (actual time=233.170..233.170 rows=531850 loops=1) похоже статистика устарела. Сделайте analyze san_materialdata. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 16:36 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
1. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
2 куда--то вот сюдой можно подумать Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
к чему индекс типа (id,detection_datetime) на san_material. но, думается, т.к. таких тагов не менее 500 000 -- это будет плохо. (0.5 -- 2.5 ляма произвольных доступов) тот случай, когда можно посмотреть возможность tag_ids integer[] в самой san_material (если оно редко обновляется). с гистами бтри_гистами и т.п. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 17:47 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwq, чото я не падумал, что ид==пк, поторопился. таки сколько записей в san_material" (без филтрации тагов) в оценке Код: sql 1.
? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 17:54 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqqwwq, чото я не падумал, что ид==пк, поторопился. таки сколько записей в san_material" (без филтрации тагов) в оценке Код: sql 1.
? 6.000.000 в таблице san_material всего 110.000.000 в таблице san_materialdata всего За эту конкретную дату примерно 500.000 в san_material 10.000.000 в san_materaildata ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 17:59 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm 6.000.000 в таблице san_material всего 110.000.000 в таблице san_materialdata всего За эту конкретную дату примерно 500.000 в san_material 10.000.000 в san_materaildataт.е в среднем 20 тагов на материал ? а сколько всего уникальных тагов ? т.е. какая вероятность того, что первый попавшийся материал имеет заданный таг ? м.б. просто бежать вдоль времени, и проверять (лейтералом и т.п.), что таг подходит ? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 18:09 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwq, 100 тагов. То есть вероятность 1 к 5, если предположить, что они равномерно повешены. По поводу проверять лейтералом можно поподробнее? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 18:24 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, `work_mem` покажите. И заодно попробуйте его поднять перед запуском запроса: Код: sql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 19:00 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
ожидаемые затраты - 50*5 произвольных доступов вдоль индекса + до ~20 [тагов в материале] -- вдоль проверяемого (полу--пессимистическая 50*5*20). если конечно вы оффсет потом не напишете. неплохо пойдет индекс (tag_id,material_id) или симметричный. чтобы вот в ту 20--ку не упираться. а лейтерал не нужен, вы из второй только фильтр дёргаете, его екзистс исполняет. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 22:55 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwq Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
ожидаемые затраты - 50*5 произвольных доступов вдоль индекса + до ~20 [тагов в материале] -- вдоль проверяемого (полу--пессимистическая 50*5*20). если конечно вы оффсет потом не напишете. неплохо пойдет индекс (tag_id,material_id) или симметричный. чтобы вот в ту 20--ку не упираться. а лейтерал не нужен, вы из второй только фильтр дёргаете, его екзистс исполняет. --поправил ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2016, 22:57 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, `work_mem` покажите. И заодно попробуйте его поднять перед запуском запроса: Код: sql 1.
4mb ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 08:48 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqqwwq Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
ожидаемые затраты - 50*5 произвольных доступов вдоль индекса + до ~20 [тагов в материале] -- вдоль проверяемого (полу--пессимистическая 50*5*20). если конечно вы оффсет потом не напишете. неплохо пойдет индекс (tag_id,material_id) или симметричный. чтобы вот в ту 20--ку не упираться. а лейтерал не нужен, вы из второй только фильтр дёргаете, его екзистс исполняет. --поправил Те же 16 секунд. Причем первоначально запрос выполнялся 150 секунд, а повторно 16. И мои оригинальные столько же. Походу 16 секунд это кэш, а 150 реальное время выполнения ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 08:52 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 08:53 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, попробуйте сделать индекс для таблицы san_material на поле detection_datetime ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 09:17 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Legushkamaxxstorm, попробуйте сделать индекс для таблицы san_material на поле detection_datetime Индекс имеется ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 09:18 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormИндекс имеется могли бы вы показать как создан индекс на detection_datetime? может попробовать делать не AND sm.detection_datetime<'2016-10-15 00:00:00+03:00' a по включительную дату: AND sm.detection_datetime<='2016-10-14 23:59:59+03:00' просто в плане не видно что бы индекс работал. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 10:15 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
LegushkamaxxstormИндекс имеется могли бы вы показать как создан индекс на detection_datetime? может попробовать делать не AND sm.detection_datetime<'2016-10-15 00:00:00+03:00' a по включительную дату: AND sm.detection_datetime<='2016-10-14 23:59:59+03:00' просто в плане не видно что бы индекс работал. А вот в первом посте я написал: Код: sql 1. 2. 3. 4. 5. 6. 7.
... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 10:16 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
LegushkamaxxstormИндекс имеется могли бы вы показать как создан индекс на detection_datetime? может попробовать делать не AND sm.detection_datetime<'2016-10-15 00:00:00+03:00' a по включительную дату: AND sm.detection_datetime<='2016-10-14 23:59:59+03:00' просто в плане не видно что бы индекс работал. Так и не должен работать учитывая авторЗа эту конкретную дату примерно 500.000 в san_material полмиллиона строк под условие. Вопрос к автору... как вы ожидаете при то что у вас 500.000 строк на дату "По идее должен выполниться быстро"? Я бы сделал индекс вида san_material(id, detection_datetime) для начала. И очень сильно бы поднял work_mem (до 32 или 64MB пока у вас не станет lossy=0 вместо lossy=240927 в плане). Скорее всего станет лучше. Ну и увеличить shared_buffers чтобы данные нормально в памяти помещались. -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 10:22 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, В первом плане было: Код: sql 1. 2. 3. 4.
Потом стало: Код: sql 1. 2. 3.
Что за сервер? И что на нём кроме базы бегает? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 11:30 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, В первом плане было: Код: sql 1. 2. 3. 4.
Потом стало: Код: sql 1. 2. 3.
Что за сервер? И что на нём кроме базы бегает? Это от разных запросов планы. На сервере еще много сервисов, rabbitmq, например. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 11:35 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Пробую выполнить другой запрос: Код: sql 1.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Выполняю запрос второй раз: Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Кэш? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 12:27 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, Скорее всего. `EXPLAIN (analyze, buffers)` покажет доступ к блокам. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 13:13 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormПробую выполнить другой запрос: Код: sql 1.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Выполняю запрос второй раз: Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Кэш? Не кеш. Ну точнее кеш не в том смысле что вы думаете. В первом случае куча данных читалась с диска (что не быстро). Во втором случае данные читались из shared buffers базы. Хотите чтобы было быстро - данные должны в shared buffers лежать (учитывая что сервер не выделенный и походу с очень медленными дисками). И про увеличение shared buffers я вам написал уже. -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 13:27 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Maxim Boguk Не кеш. Ну точнее кеш не в том смысле что вы думаете. В первом случае куча данных читалась с диска (что не быстро). Во втором случае данные читались из shared buffers базы. Хотите чтобы было быстро - данные должны в shared buffers лежать (учитывая что сервер не выделенный и походу с очень медленными дисками). И про увеличение shared buffers я вам написал уже. -- Maxim Boguk www.postgresql-consulting.ru Но база весит 50гб, а shared buffers у меня 16 гб. Как быть? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 13:46 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
надо бороться за другой план : в ожидании,, что условие фильтра вдоль индекса "" Код: sql 1.
у вас выполняется довольно часто, и 50 наберется быстро. как загнать -- надо думать. я предлагал авториндекс (tag_id,material_id) (10--20 отыграть множитель) но попробуйте [без этого индекса] LIMIT 1 пока поставить в итоге, вместо 50 . потом костами (не помню, но каким то костом запинывалось) или енейблами хеш--агг/джойн ('enable_hashagg','enable_hashjoin' TO OFF) отключить -- посмотрим, как быстро вдоль индекса по detection_datetime условие фильтра срабатывает. не надо нам эти пол--ляма читать, а потом сортировать дикие выборки, думаю. (там на 50 умножить -- время оценить) но если фильтр не так часто -- то тогда пж всё правильно делает. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 14:26 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, Скорее всего. `EXPLAIN (analyze, buffers)` покажет доступ к блокам. Показывает вот что: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Я так понимаю, что 271373 записи уже были в буфере? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 14:34 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
вспомнил, как запинывать без енейблов : qwwqqwwq Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
ожидаемые затраты - 50*5 произвольных доступов вдоль индекса + до ~20 [тагов в материале] -- вдоль проверяемого (полу--пессимистическая 50*5*20). если конечно вы оффсет потом не напишете. неплохо пойдет индекс (tag_id,material_id) или симметричный. чтобы вот в ту 20--ку не упираться. а лейтерал не нужен, вы из второй только фильтр дёргаете, его екзистс исполняет. --поправил и покажите план, даже если плохой . (если не дождетесь аналайза -- то просто план) ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 14:43 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqвспомнил, как запинывать без енейблов : qwwqпропущено... --поправил и покажите план, даже если плохой . (если не дождетесь аналайза -- то просто план) С limit 1 очень быстро работает(и первоначальный запрос тоже): Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
А если поставить limit 10, то уже идет по другому плану ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 14:53 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, Ну вот -- 23 лупа на попадание в фильтр, как ожидалось. т.е. бороться за такой план стоит можно конечно угробище родить в стиле а-ля лузскан ( "with recursive " -- вот это вот всё), но лучше енейблами запинать. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 15:03 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqНу вот -- 23 лупа на попадание в фильтр что--то не то посмотрел : Код: sql 1.
--- а, кажется все правильно. 23 лупа вдоль времени, а в нутре еще фильтр по тагу сработал на 18--й раз. Был бы составной -- было бы в этот раз в 18 раз дешевле. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 15:08 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormПоказывает вот что: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Я так понимаю, что 271373 записи уже были в буфере? Это не записи, это блоки, каждый по 8192 байта. Запрос поднимает слишком много холодных данных с дисков. Вам его следует переписать -- если для `LIMIT 1` запрос отрабатывает быстро, loose index scan может помочь. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 15:39 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqmaxxstorm, Ну вот -- 23 лупа на попадание в фильтр, как ожидалось. т.е. бороться за такой план стоит можно конечно угробище родить в стиле а-ля лузскан ( "with recursive " -- вот это вот всё), но лучше енейблами запинать. Я все равно не понимаю, почему планы разные для разных лимитов? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 16:03 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormqwwqmaxxstorm, Ну вот -- 23 лупа на попадание в фильтр, как ожидалось. т.е. бороться за такой план стоит можно конечно угробище родить в стиле а-ля лузскан ( "with recursive " -- вот это вот всё), но лучше енейблами запинать. Я все равно не понимаю, почему планы разные для разных лимитов? патамушта "вдоль индекса" заканчивает чтение тогда, когда набирается LIMIT (такой унутре там луп с выходом по условию лимита) , и оценка цены (cost) растёт линейно с ограничением в лимите. а план для хеш-а вычитывает всё (что нужно соединять) всегда, и лимит берёт уже после соединения этого всего и сорта всего насоединенного (а вот "вдоль индекса" ресорт не нужен). т.е. его цена константна (для заданных статистик). вы можете подсобрать статистику наново, подкрутить косты (сделать цену рендом доступа не 4, а скажем 2), и напрямую залочить для вашего запроса енейблы хеш--траляля (см выше). но это грубо. тонко -- написать with recursive перебор, и добавить удешевляющий его индекс (тогда и хак с +0 убрать). есть ещё подозрение, что у вас табличка (одна из, или обе) может сильно апдейтиться -- тогда в цену войдет лишняя пробежка по дед-ровсам, например. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 17:19 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqmaxxstormпропущено... Я все равно не понимаю, почему планы разные для разных лимитов? патамушта "вдоль индекса" заканчивает чтение тогда, когда набирается LIMIT (такой унутре там луп с выходом по условию лимита) , и оценка цены (cost) растёт линейно с ограничением в лимите. а план для хеш-а вычитывает всё (что нужно соединять) всегда, и лимит берёт уже после соединения этого всего и сорта всего насоединенного (а вот "вдоль индекса" ресорт не нужен). т.е. его цена константна (для заданных статистик). вы можете подсобрать статистику наново, подкрутить косты (сделать цену рендом доступа не 4, а скажем 2), и напрямую залочить для вашего запроса енейблы хеш--траляля (см выше). но это грубо. тонко -- написать with recursive перебор, и добавить удешевляющий его индекс (тогда и хак с +0 убрать). есть ещё подозрение, что у вас табличка (одна из, или обе) может сильно апдейтиться -- тогда в цену войдет лишняя пробежка по дед-ровсам, например. Андейтится да, довольно часто ... |
|||
:
Нравится:
Не нравится:
|
|||
17.10.2016, 17:22 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqmaxxstormпропущено... Я все равно не понимаю, почему планы разные для разных лимитов? патамушта "вдоль индекса" заканчивает чтение тогда, когда набирается LIMIT (такой унутре там луп с выходом по условию лимита) , и оценка цены (cost) растёт линейно с ограничением в лимите. а план для хеш-а вычитывает всё (что нужно соединять) всегда, и лимит берёт уже после соединения этого всего и сорта всего насоединенного (а вот "вдоль индекса" ресорт не нужен). т.е. его цена константна (для заданных статистик). вы можете подсобрать статистику наново, подкрутить косты (сделать цену рендом доступа не 4, а скажем 2), и напрямую залочить для вашего запроса енейблы хеш--траляля (см выше). но это грубо. тонко -- написать with recursive перебор, и добавить удешевляющий его индекс (тогда и хак с +0 убрать). есть ещё подозрение, что у вас табличка (одна из, или обе) может сильно апдейтиться -- тогда в цену войдет лишняя пробежка по дед-ровсам, например. Помогите написать with recursive. Не могу понять как ... |
|||
:
Нравится:
Не нравится:
|
|||
18.10.2016, 15:41 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormqwwqпропущено... патамушта "вдоль индекса" заканчивает чтение тогда, когда набирается LIMIT (такой унутре там луп с выходом по условию лимита) , и оценка цены (cost) растёт линейно с ограничением в лимите. а план для хеш-а вычитывает всё (что нужно соединять) всегда, и лимит берёт уже после соединения этого всего и сорта всего насоединенного (а вот "вдоль индекса" ресорт не нужен). т.е. его цена константна (для заданных статистик). вы можете подсобрать статистику наново, подкрутить косты (сделать цену рендом доступа не 4, а скажем 2), и напрямую залочить для вашего запроса енейблы хеш--траляля (см выше). но это грубо. тонко -- написать with recursive перебор, и добавить удешевляющий его индекс (тогда и хак с +0 убрать). есть ещё подозрение, что у вас табличка (одна из, или обе) может сильно апдейтиться -- тогда в цену войдет лишняя пробежка по дед-ровсам, например. Помогите написать with recursive. Не могу понять как "по одной записи вдоль индекса" а с каким лимитом план ещё такой ? может быть запинаем пересбором статистики, не ? а то предвижу геморрой, так как индекс по неуникальному полю, надо писать в ордер бай уникализирующий постфикс, а это поделие передовых студентов камнедробилки(тм) сразу свалится в сорт по всей выборке, придётся писать ручной проход (внутри той же конструкции) только до следующего значения вдоль неуникального индекса с ручной же сортировкой частичной выборки. или , для простоты, построить индекс (дата, ид) -- уникальный за счет постфикса "ид", и бегать с гораздо меньшим хенджобом вдоль него. т.е. на страничку А4 будет запрос, с кучкой трюков -- оно вам надо ? ... |
|||
:
Нравится:
Не нравится:
|
|||
18.10.2016, 16:14 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqmaxxstormпропущено... Помогите написать with recursive. Не могу понять как "по одной записи вдоль индекса" а с каким лимитом план ещё такой ? может быть запинаем пересбором статистики, не ? а то предвижу геморрой, так как индекс по неуникальному полю, надо писать в ордер бай уникализирующий постфикс, а это поделие передовых студентов камнедробилки(тм) сразу свалится в сорт по всей выборке, придётся писать ручной проход (внутри той же конструкции) только до следующего значения вдоль неуникального индекса с ручной же сортировкой частичной выборки. или , для простоты, построить индекс (дата, ид) -- уникальный за счет постфикса "ид", и бегать с гораздо меньшим хенджобом вдоль него. т.е. на страничку А4 будет запрос, с кучкой трюков -- оно вам надо ? С limit 4 план такой же, а вот 5 уже тот старый. Что значит запинаем статистикой? Авто analyze? ... |
|||
:
Нравится:
Не нравится:
|
|||
18.10.2016, 16:18 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
[quot qwwq]maxxstormхак с +0 qwwq, мог бы поподробнее рассказать или кинуть ссылку про этот хак: когда в каких случаях помогает/использовать? :) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2016, 09:09 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Legushka, Индексируются значения аттрибутов (колонки таблиц или результаты функций). Если в запросе использовать не сам аттрибут, а выражение с ним (включая явное/неявное приведение типов), то индекс неприменим. В данном случае, если к индексированной числовой колонке прибавить 0, то значение колонки не измениться, но вот индекс уже применить нельзя, т.к. выборка делается не по атрибуту, а по результату выражения над ним. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2016, 13:35 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqвспомнил, как запинывать без енейблов : qwwqпропущено... --поправил и покажите план, даже если плохой . (если не дождетесь аналайза -- то просто план) На другой бд(тестовой) выполняется дольше этот запрос: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
С чем это может быть связано? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2016, 15:05 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Причем даже если поставить limit 50, то план запроса не меняется: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2016, 15:39 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwq Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
ожидаемые затраты - 50*5 произвольных доступов вдоль индекса + до ~20 [тагов в материале] -- вдоль проверяемого (полу--пессимистическая 50*5*20). если конечно вы оффсет потом не напишете. неплохо пойдет индекс (tag_id,material_id) или симметричный. чтобы вот в ту 20--ку не упираться. а лейтерал не нужен, вы из второй только фильтр дёргаете, его екзистс исполняет. не сразу прочитал про оффсет, а он будет нужен потом( Так что backword не подходит походу ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2016, 16:28 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormне сразу прочитал про оффсет, а он будет нужен потом( Так что backword не подходит походу с этого бы и начинали любителей пагинации оффсетом не лечим совсем как и любителей отрезать хвост собакам тонкими слайсами или искать следующий (от текущего "n--го") элемент в связанном списке -- перебором всех n+1 от начала, а не прямым переходом к next т.е. принципиально неоперабельные клинические случаи тогда ПЖ вам все правильно делает -- соединяет всё со всем, всё до конца сортирует, и , старательно слюнявя пальчик, отсчитывает в этой бескрайней простынке с нужного места по нужное место. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2016, 17:16 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqmaxxstormне сразу прочитал про оффсет, а он будет нужен потом( Так что backword не подходит походу с этого бы и начинали любителей пагинации оффсетом не лечим совсем как и любителей отрезать хвост собакам тонкими слайсами или искать следующий (от текущего "n--го") элемент в связанном списке -- перебором всех n+1 от начала, а не прямым переходом к next т.е. принципиально неоперабельные клинические случаи тогда ПЖ вам все правильно делает -- соединяет всё со всем, всё до конца сортирует, и , старательно слюнявя пальчик, отсчитывает в этой бескрайней простынке с нужного места по нужное место. А какие еще варианты для пагинации? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2016, 17:21 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm ... А какие еще варианты для пагинации? от достигнутого [WHERE {unique_index_list}>{last_index_row} ORDER BY {unique_index_list} LIMIT $Page ] или однопроходный -- "сразу всё" с сохранением нарезки границ у всех есть свои модельные ограничения, [как и у многократного оффсета в быстроменяющейся обстановке]. но затрат сильно меньше ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2016, 17:32 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormА какие еще варианты для пагинации? http://www.slideshare.net/MarkusWinand/p2d2-pagination-done-the-postgresql-way ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2016, 19:49 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqmaxxstorm ... А какие еще варианты для пагинации? от достигнутого [WHERE {unique_index_list}>{last_index_row} ORDER BY {unique_index_list} LIMIT $Page ] или однопроходный -- "сразу всё" с сохранением нарезки границ у всех есть свои модельные ограничения, [как и у многократного оффсета в быстроменяющейся обстановке]. но затрат сильно меньше Добавил индекс по tag_id, material_id. Теперь backword план работает при лимите 1000. Осталось переписать пагинацию ... |
|||
:
Нравится:
Не нравится:
|
|||
20.10.2016, 09:44 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Вот план: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
Еще вопрос, если я добавлю в exist еще одно поле(stop=false), мне надо будет сделать тройной индекс (tag_id, material_id, stop) или просто добавить к существующему (tag_id, material_id) одинарный индекс на поле stop? Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.10.2016, 10:25 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
После создания индекса (material_id, tag_id) выяснилось, что есть теги, которые редко встречаются и для них план запрос "вдоль индекса не подходит", зато старый(джойн) работает быстро. Для сравнения 2 разных плана для одного и того же запроса: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.10.2016, 16:11 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormПосле создания индекса (material_id, tag_id) выяснилось, что есть теги, которые редко встречаются и для них план запрос "вдоль индекса не подходит"... Код: sql 1. 2. 3. 4. 5. 6. 7.
получается по 1000 пустых поисков на запись, а не по 20, как ожидалось. т.е. в 50 раз дороже ожидаемого. можете в таблицах тагов вести колонку "статистики" частотности тега, и по ней выбирать запрос, который натравливать на ваш таг. (вот так , да, всё ручками). второй вариант -- вести массивы тагов (tags int[]) материала в той же таблице, где даты. в новом поле. пользоваться btree_gist смешанным индексом (data,tags) . Никаких джойнов -- все в одном. но при частых апдейтах это будет скорее головной болью, чем решением. хотя рискнуть можно. все удобства от Бортунова и К. они это всё в свое время понаписали. по поводу "стопа" -- надо смотреть , зачем он вам. есть много вариаций. условный индекс в т.ч. (WHERE NOT stop), а в составном оно д.б. первым номером. в конце оно бессмысленно. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.10.2016, 18:01 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwq получается по 1000 пустых поисков на запись, а не по 20, как ожидалось. т.е. в 50 раз дороже ожидаемого. можете в таблицах тагов вести колонку "статистики" частотности тега, и по ней выбирать запрос, который натравливать на ваш таг. (вот так , да, всё ручками). второй вариант -- вести массивы тагов (tags int[]) материала в той же таблице, где даты. в новом поле. пользоваться btree_gist смешанным индексом (data,tags) . Никаких джойнов -- все в одном. но при частых апдейтах это будет скорее головной болью, чем решением. хотя рискнуть можно. все удобства от Бортунова и К. они это всё в свое время понаписали. по поводу "стопа" -- надо смотреть , зачем он вам. есть много вариаций. условный индекс в т.ч. (WHERE NOT stop), а в составном оно д.б. первым номером. в конце оно бессмысленно. Спасибо за советы, вы очень помогли. Еще вопрос из той же области. Есть 2 БД одинаковой структуры, тест и бой. Один и тот же запрос идет по разным планам(таблицы те же): Код: sql 1. 2. 3.
Тест: Код: sql 1. 2. 3. 4. 5. 6.
Бой: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
В чем причина? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2016, 13:04 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, по всему, у вас данные разные. в тест "actual time=0.049..0.053 rows=3 loops=1", в боевом"actual time=1321.956..1321.956 rows=0 loops=1". с разными данными, их количеством, или распределением по таблице, можно получить разные планы. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2016, 13:35 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Lonepsychomaxxstorm, по всему, у вас данные разные. в тест "actual time=0.049..0.053 rows=3 loops=1", в боевом"actual time=1321.956..1321.956 rows=0 loops=1". с разными данными, их количеством, или распределением по таблице, можно получить разные планы. На боевом их больше в 1.5 раза. Я понимаю, что проблема решается составным индексом (tag_id, material_id), но все равно интересно знать почему так происходит. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2016, 13:39 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormqwwqполучается по 1000 пустых поисков на запись, а не по 20, как ожидалось. т.е. в 50 раз дороже ожидаемого. можете в таблицах тагов вести колонку "статистики" частотности тега, и по ней выбирать запрос, который натравливать на ваш таг. (вот так , да, всё ручками). второй вариант -- вести массивы тагов (tags int[]) материала в той же таблице, где даты. в новом поле. пользоваться btree_gist смешанным индексом (data,tags) . Никаких джойнов -- все в одном. но при частых апдейтах это будет скорее головной болью, чем решением. хотя рискнуть можно. все удобства от Бортунова и К. они это всё в свое время понаписали. по поводу "стопа" -- надо смотреть , зачем он вам. есть много вариаций. условный индекс в т.ч. (WHERE NOT stop), а в составном оно д.б. первым номером. в конце оно бессмысленно. Спасибо за советы, вы очень помогли. Еще вопрос из той же области. Есть 2 БД одинаковой структуры, тест и бой. Один и тот же запрос идет по разным планам(таблицы те же): Код: sql 1. 2. 3.
Тест: Код: sql 1. 2. 3. 4. 5. 6.
Бой: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
В чем причина? причина в cost--based оптимизации и статистиках, на которые она опирается. например почему то для заданного материал_ид оно ожидает 1869 строк, а находит 6 -- разница более чем в 2 порядка. как вот оно так ? вы давно статистику собирали ? или индекс нажрался мертвых строк ? то же по тагам -- ожидания в 3 раза меньше реальности. ну это нщё сносно. сделайте енейбл битмап скан ту офф -- и посмотрите на оценку цены в плане для "хорошего" плана. в пж слишком мало костовых констант -- видимо оптимайзер модельно очень дубовый. костами спихнуть с одного индексного поиска на другой тип индексного же поиска не удастся, думаю, хотя можно попробовать. (а енейблы сосут при 10^9 строк, т.к. "большая" константа пропадает на фоне). ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2016, 15:00 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqпричина в cost--based оптимизации и статистиках, на которые она опирается. например почему то для заданного материал_ид оно ожидает 1869 строк, а находит 6 -- разница более чем в 2 порядка. как вот оно так ? вы давно статистику собирали ? или индекс нажрался мертвых строк ? то же по тагам -- ожидания в 3 раза меньше реальности. ну это нщё сносно. сделайте енейбл битмап скан ту офф -- и посмотрите на оценку цены в плане для "хорошего" плана. в пж слишком мало костовых констант -- видимо оптимайзер модельно очень дубовый. костами спихнуть с одного индексного поиска на другой тип индексного же поиска не удастся, думаю, хотя можно попробовать. (а енейблы сосут при 10^9 строк, т.к. "большая" константа пропадает на фоне). Статистику собирал непосредственно перед запросом. Насчет мертвых строк сомневаюсь. Когда они появляются? При делетах? Если выключить битмапскан, то план хороший: Код: sql 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2016, 15:12 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormЕсли выключить битмапскан, то план хороший: Код: sql 1. 2. 3. 4. 5. 6.
вот у вас оценка пессимистическая "6676.53" при ожидании 4 строк. она больше пессимистической оценки для битмапа (cost=5262.46..5278.50). а вот откуда она такая большая ? я бы с потолка насчитал 4 произвольных ценой (если не крутили) по 4 + найти нужную страничку индексов -- чтонть пессимистически странички 4 -- максимум 20--32 по произвольным набегает. откуда это вот угрёбище нагребает 6676.53 -- тайна великая есть. могабыть в статистике что ? и зачем сравнивает только писси-мяссиские велчичины. "и вот всё у них так."(сс) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2016, 16:24 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwq, всё время путаюсь. диапазон костов -- это оценка затрат на вывод первой и последней строки соответственно. из 4. а не пессимистич/оптимистич. см https://habrahabr.ru/post/203320/ вот откуда оно 6000 набрало -- хз ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2016, 16:34 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwq, Оценка строится на `%_cost` параметрах. Основная доля там — обращение к страницам, для индексов это `random_page_cost`. Учитвыая, что ожидается всего 4 записи и также то, что индекс читается не весь, а "по дереву", то оценка в 6600 довольна высока. Возможно (я не разбирался в оценке индексных доступов, только последовательных) сюда закладывается также и доступ к 4-м (в худшем случае) блокам из основной таблицы. Но всё равно — это очень много для 4-х записей. А что выведет `EXPLAIN (analyze, buffers)`? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2016, 16:46 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovqwwq, Оценка строится на `%_cost` параметрах. Основная доля там — обращение к страницам, для индексов это `random_page_cost`. Учитвыая, что ожидается всего 4 записи и также то, что индекс читается не весь, а "по дереву", то оценка в 6600 довольна высока. Возможно (я не разбирался в оценке индексных доступов, только последовательных) сюда закладывается также и доступ к 4-м (в худшем случае) блокам из основной таблицы. Но всё равно — это очень много для 4-х записей. А что выведет `EXPLAIN (analyze, buffers)`? Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2016, 16:50 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Если без скана, то Код: sql 1. 2. 3. 4. 5. 6. 7.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2016, 17:13 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovqwwq, Оценка строится на `%_cost` параметрах. Основная доля там — обращение к страницам, для индексов это `random_page_cost`. Учитвыая, что ожидается всего 4 записи и также то, что индекс читается не весь, а "по дереву", то оценка в 6600 довольна высока. Возможно (я не разбирался в оценке индексных доступов, только последовательных) сюда закладывается также и доступ к 4-м (в худшем случае) блокам из основной таблицы. Но всё равно — это очень много для 4-х записей. А что выведет `EXPLAIN (analyze, buffers)`? я вот думаю, что ожидается 4 записи после фильтра. м.б. до фильтра ожидается какое--то безумное число ? надо бы пошаманить -- посмотреть что в pg_statistic валяется и как это м.б. связано с той цифирью, которую мы видим как результат накрутки костов для 4--х доступов. думаю -- все таки бага где--то. или мы какой--то инфы о модели не знаем (стотысячмиллионов апдейтов, например) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2016, 18:33 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2016, 18:42 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormvyegorovqwwq, Оценка строится на `%_cost` параметрах. Основная доля там — обращение к страницам, для индексов это `random_page_cost`. Учитвыая, что ожидается всего 4 записи и также то, что индекс читается не весь, а "по дереву", то оценка в 6600 довольна высока. Возможно (я не разбирался в оценке индексных доступов, только последовательных) сюда закладывается также и доступ к 4-м (в худшем случае) блокам из основной таблицы. Но всё равно — это очень много для 4-х записей. А что выведет `EXPLAIN (analyze, buffers)`? Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
А у вас случайно 1)default_statistics_target на тесте и в бою не отличается? 2)случайно не выставлен руками n_distinct на san_materialdata_eb4b9aaa.material_id в тесте или другое значение statistic? Что говорит Код: plsql 1.
в бою и в тесте? И меняется ли что то после ручного выполнения analyze san_materialdata_eb4b9aaa; в бою и в тесте в результатах explain analyze? Вероятнее всего не хватает статистки в бою адекватной и надо будет или statistics поднимать для поля (или по всей базе) или n_distinct ему руками прописывать. -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
27.10.2016, 03:31 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Maxim BogukА у вас случайно 1)default_statistics_target на тесте и в бою не отличается? 2)случайно не выставлен руками n_distinct на san_materialdata_eb4b9aaa.material_id в тесте или другое значение statistic? Что говорит Код: plsql 1.
в бою и в тесте? И меняется ли что то после ручного выполнения analyze san_materialdata_eb4b9aaa; в бою и в тесте в результатах explain analyze? Вероятнее всего не хватает статистки в бою адекватной и надо будет или statistics поднимать для поля (или по всей базе) или n_distinct ему руками прописывать. -- Maxim Boguk www.postgresql-consulting.ru 1) default_statistics_target одинаковая, равна 100 2) n_distinct руками не ставился, но он различается, на бою 63880, на тесте 47247 3) Для explain analyze select * from san_materialdata_eb4b9aaa where material_id = 5858304 планы тоже различаются: Бой: Код: sql 1. 2. 3. 4. 5. 6. 7.
Тест: Код: sql 1. 2. 3. 4.
Однако, после сбора статистики, план на бою становится таким же как на тесте, что нельзя сказать о первоначальном запросе. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.10.2016, 09:12 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
планировщик считает кост не для 4 строк, а для 1878, поэтому такая оценка большая. что выдает запрос Код: sql 1.
? скорей всего надо будет добавить статистики по этому полю, чтобы не было ошибки на 2 порядка: Код: sql 1. 2.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.10.2016, 11:32 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Alexius планировщик считает кост не для 4 строк, а для 1878, поэтому такая оценка большая. что выдает запрос Код: sql 1.
? скорей всего надо будет добавить статистики по этому полю, чтобы не было ошибки на 2 порядка: Код: sql 1. 2.
Вот что выдает: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.10.2016, 11:37 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Alexiusalter table san_materialdata alter column material_id set statistics 1000; analyze san_materialdata; [/src] Сделал, план запроса стал хорошим: Код: sql 1. 2. 3. 4. 5. 6. 7.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.10.2016, 11:43 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Еще похожая проблема с запросом Код: sql 1. 2. 3.
Выдает план: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
Однако, если взять другой тег Код: sql 1. 2. 3.
или меньший интервал Код: sql 1. 2. 3.
то план тот, что нужно: Код: sql 1. 2. 3. 4. 5. 6. 7.
Насколкьо страшно будет, если отключить enable_bitmapscan? Как решить без отключения? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.11.2016, 14:23 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
А вот для другого тега план такой же, но ожидаемое количество записей на порядок меньше реального: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2016, 17:20 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, я подозреваю что нужно аналогично добавить собираемой статистики по полю tag_id, раз планер ошибается в оценке. по приведенным планам правда не понятно, они все без analyze, кроме последнего. для тестов отключать enable_* параметры очень полезно чтобы перебрать планы для фиксированного запроса и разобраться. на практике это обычно крайняя мера, когда по-другому совсем никак, что бывает редко. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.11.2016, 18:10 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Alexiusmaxxstorm, я подозреваю что нужно аналогично добавить собираемой статистики по полю tag_id, раз планер ошибается в оценке. по приведенным планам правда не понятно, они все без analyze, кроме последнего. для тестов отключать enable_* параметры очень полезно чтобы перебрать планы для фиксированного запроса и разобраться. на практике это обычно крайняя мера, когда по-другому совсем никак, что бывает редко. Добавил статистики по полю tag_ig также до 1000. Отключил enable_bitmapscan. Вот что получается: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
Почему он пытается агрегировать? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.11.2016, 11:20 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Отключаю enable_hashagg, получается еще интереснее: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
... |
|||
:
Нравится:
Не нравится:
|
|||
10.11.2016, 11:21 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, Надо же не просто план смотреть, а время, сколько занимает исполнение запроса с таким планом, и кол-во буферов. EXPLAIN (analyze, buffers) ... |
|||
:
Нравится:
Не нравится:
|
|||
10.11.2016, 12:02 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm Почему он пытается агрегировать? патамушта каунт -- агрегатная ф--я. приведите сам запрос еще раз, а то последнее : Код: plaintext
наводят на мысли о наличии count(distinct ...) ... |
|||
:
Нравится:
Не нравится:
|
|||
10.11.2016, 12:49 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqmaxxstormПочему он пытается агрегировать? патамушта каунт -- агрегатная ф--я. приведите сам запрос еще раз, а то последнее : Код: plaintext
наводят на мысли о наличии count(distinct ...) Код: sql 1. 2. 3.
Я понимаю, что функция агрегатная, но почему иногда по индексу идет, а иногда битмап хип скан/агрегейт? Индекс (material_id, tag_id) не уникален, так как значения могут повторяться(несколько одинаковых тегов на один материал). Из-за этого? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.11.2016, 12:53 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, Надо же не просто план смотреть, а время, сколько занимает исполнение запроса с таким планом, и кол-во буферов. EXPLAIN (analyze, buffers) Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Статистика по полю material_id 1000, но все равно ошибается планировщик. Почему? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.12.2016, 11:19 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, покажите результаты выполнения запроса: Код: sql 1.
я правильно понял, что в san_materialdata 110М строк и среди них 6М уникальных material_id ? после того, как добавлялась статистика, analyze san_materialdata делался? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.12.2016, 21:10 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Alexiusmaxxstorm, покажите результаты выполнения запроса: Код: sql 1.
я правильно понял, что в san_materialdata 110М строк и среди них 6М уникальных material_id ? после того, как добавлялась статистика, analyze san_materialdata делался? Результат выполнения: 3.31129e+06 В san_materialdata порядка 150М строк и уникальных material_id 10М. analyze san_materialdata делался, в том числе и автоматически каждую ночь делается. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 09:32 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, А можно вывод такого запроса глянуть: Код: sql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 12:19 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, А можно вывод такого запроса глянуть: Код: sql 1.
"material_id"; 0;3.31129e+06; 0.719951 "tag_id"; 0;137; -0.0315493 ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 12:20 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqприведите сам запрос еще раз, а то последнее : Код: plaintext
наводят на мысли о наличии count(distinct ...) Оптимизатор понимает, что ему достаточно выдать уникальные значения и рассматривает `GROUP BY` по подзапросу. И судя по всему он находит его привлекательным, даже с отключенным HashAgg. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 12:51 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormРезультат выполнения: 3.31129e+06 В san_materialdata порядка 150М строк и уникальных material_id 10М. analyze san_materialdata делался, в том числе и автоматически каждую ночь делается. не сходится что-то оценка планировщика с ожидаемой в строке с HashAggregate. а можно вывод запросов Код: sql 1. 2.
для каждой строки из san_material есть соответствующая запись в san_materialdata ? ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 13:15 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Alexius, и еще раз план последнего запроса на всякий случай (можно без analyze), может n_distinct изменился и поэтому не сходится. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 13:17 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Alexius не сходится что-то оценка планировщика с ожидаемой в строке с HashAggregate. а можно вывод запросов Код: sql 1. 2.
для каждой строки из san_material есть соответствующая запись в san_materialdata ? "Seq Scan on san_materialdata (cost=0.00..3704419.36 rows=167943136 width=62)" "Seq Scan on san_material (cost=0.00..2623611.56 rows=12420256 width=1129)" Не для каждой строки есть запись. Могут быть записи в san_material без тегов(записей в san_materialdata) ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 13:18 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
AlexiusAlexius, и еще раз план последнего запроса на всякий случай (можно без analyze), может n_distinct изменился и поэтому не сходится. Сделал еще раз analyze san_materialdata, теперь n_distinct немного поменялся: Код: sql 1. 2.
Старый запрос(за 1 день) идет теперь по индексу: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
однако, если взять интервал за 2 дня, то картина та же: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 13:51 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, Ну... n_distinct в 5 раз меньше стал, это много! И теперь расчёты совпадают. Вы ловите неприятный эффект того, что планировщик не знает о том, что `san_material.material_id` и `san_material.detection_datetime` коррелируют. Тут несколько вариантов как "вправить мозг": - `CREATE INDEX CONCURRENTLY i_san_materialdata_tag_n_id ON san_materialdata(tag_id, material_id)` -- чтобы подзапрос быстрее отрабатывал и лучше планировался. - `CREATE INDEX CONCURRENTLY i_san_material_dtime_id ON san_material(detection_time, id)` -- планировщик сможет точнее оценить кол-во ID-шек в заданном диапазоне дат и не идти по ПК (да и IOS может выйти) - `CREATE INDEX CONCURRENTLY i_san_material_id_dtime ON san_material(id, detection_time)` -- так корректнее, поскольку диапазоны надо ставить в конце (дата обычно на больше-меньше проверяется, id -- на соответствие). ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 15:23 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, Ну... n_distinct в 5 раз меньше стал, это много! И теперь расчёты совпадают. Вы ловите неприятный эффект того, что планировщик не знает о том, что `san_material.material_id` и `san_material.detection_datetime` коррелируют. Тут несколько вариантов как "вправить мозг": - `CREATE INDEX CONCURRENTLY i_san_materialdata_tag_n_id ON san_materialdata(tag_id, material_id)` -- чтобы подзапрос быстрее отрабатывал и лучше планировался. - `CREATE INDEX CONCURRENTLY i_san_material_dtime_id ON san_material(detection_time, id)` -- планировщик сможет точнее оценить кол-во ID-шек в заданном диапазоне дат и не идти по ПК (да и IOS может выйти) - `CREATE INDEX CONCURRENTLY i_san_material_id_dtime ON san_material(id, detection_time)` -- так корректнее, поскольку диапазоны надо ставить в конце (дата обычно на больше-меньше проверяется, id -- на соответствие). Первый индекс уже есть, а вот второй надо попробовать. Однако, щас другая проблема, один и тот же запрос отрабатывает с большой разницей по времени, когда читает с диска и из шаред буфера: Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Неужели прочитать с диска 10521 блоков занимает 22 секунды? ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 16:04 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, Ну... n_distinct в 5 раз меньше стал, это много! И теперь расчёты совпадают. Вы ловите неприятный эффект того, что планировщик не знает о том, что `san_material.material_id` и `san_material.detection_datetime` коррелируют. Тут несколько вариантов как "вправить мозг": - `CREATE INDEX CONCURRENTLY i_san_materialdata_tag_n_id ON san_materialdata(tag_id, material_id)` -- чтобы подзапрос быстрее отрабатывал и лучше планировался. - `CREATE INDEX CONCURRENTLY i_san_material_dtime_id ON san_material(detection_time, id)` -- планировщик сможет точнее оценить кол-во ID-шек в заданном диапазоне дат и не идти по ПК (да и IOS может выйти) - `CREATE INDEX CONCURRENTLY i_san_material_id_dtime ON san_material(id, detection_time)` -- так корректнее, поскольку диапазоны надо ставить в конце (дата обычно на больше-меньше проверяется, id -- на соответствие). Вот здесь время равно ошибка планировщика в HashAggregate 677909 строк вместо ожидаемых 4575: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 16:14 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormvyegorovmaxxstorm, Ну... n_distinct в 5 раз меньше стал, это много! И теперь расчёты совпадают. Вы ловите неприятный эффект того, что планировщик не знает о том, что `san_material.material_id` и `san_material.detection_datetime` коррелируют. Тут несколько вариантов как "вправить мозг": - `CREATE INDEX CONCURRENTLY i_san_materialdata_tag_n_id ON san_materialdata(tag_id, material_id)` -- чтобы подзапрос быстрее отрабатывал и лучше планировался. - `CREATE INDEX CONCURRENTLY i_san_material_dtime_id ON san_material(detection_time, id)` -- планировщик сможет точнее оценить кол-во ID-шек в заданном диапазоне дат и не идти по ПК (да и IOS может выйти) - `CREATE INDEX CONCURRENTLY i_san_material_id_dtime ON san_material(id, detection_time)` -- так корректнее, поскольку диапазоны надо ставить в конце (дата обычно на больше-меньше проверяется, id -- на соответствие). Первый индекс уже есть, а вот второй надо попробовать. Однако, щас другая проблема, один и тот же запрос отрабатывает с большой разницей по времени, когда читает с диска и из шаред буфера: Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Неужели прочитать с диска 10521 блоков занимает 22 секунды? Если у вас не ssd а механика то у вас в лучшем случае 15.000RPM диски а скорее всего 10.000RPM... максимум что можно с такого диска иметь это 200-250 случайных чтений в секунду, так что 22 секунды - еще приличный вполне результат (могло быть и в 2-3 раза медленнее легко). ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 16:15 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormВот здесь время равно ошибка планировщика в HashAggregate 677909 строк вместо ожидаемых 4575: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
А ПЖ не может (пока, надеюсь) увидеть корреляцию. У `san_materialdata.material_id` 650k уникальных значений. А из таблицы, по предикату `tag_id=602` выбирается 0.7% записей. Вот база и берёт эти самые 0.7% от 650k. И очень неловко, что по факту попадают... все, и даже чуть больше. Кстати, вопрос -- почему HashAgg возвращает больше, чем n_distinct?.. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 16:52 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormВот здесь время равно ошибка планировщика в HashAggregate 677909 строк вместо ожидаемых 4575: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
есть 2 варианта как это исправить. проблема в том, что на большой таблице сложно корректно оценить число различных значений поля (n_distinct) в некоторых случаях по небольшой выборке, которую делает analyze. 1) можно увеличить stats target для поля material_id еще больше, до 5000 или максимума 10000. минусы: analyze будет дольше (но это обычно не проблема), планирование запросов с этим полем может быть дольше - это может быть в некоторых случаях критично, если например есть много простых быстрых запросов с этой таблицей. 2) подсчитать действительное число различных material_id в этой таблице Код: sql 1.
таким запросом скорей всего будет быстрее (если там будет hashaggregate. стоит предварительно убедиться в этом и если нет - то увеличить work_mem в сессии). далее разделить его на 167943136 или сколько к тому моменту будет строк в таблице. и прописать полученное значение со знаком минус через alter table san_materialdata alter column material_id set (n_distinct = x); знак минус тут говорит планировщику что у нас не число различных значений, а отношение числа уникальных значений к общему числу строк. вполне вероятно что это соотношение в будущем не будет сильно меняться и достаточно его таким образом один раз "прибить гвоздями". ... |
|||
:
Нравится:
Не нравится:
|
|||
02.12.2016, 20:15 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Maxim BogukЕсли у вас не ssd а механика то у вас в лучшем случае 15.000RPM диски а скорее всего 10.000RPM... максимум что можно с такого диска иметь это 200-250 случайных чтений в секунду, так что 22 секунды - еще приличный вполне результат (могло быть и в 2-3 раза медленнее легко). Не поверю, что чтобы прочитать 90000 строк из индекса, понадобится 365 секунд: Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
dirtied это что за блоки? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 09:06 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, База читает не по-строчно, а по-блочно. Было `read=275479` произвольных обращений к диску. Чтобы точно знать время IO операций, можно включить `track_io_timing=on`, тогда в плане будет видно реальное время работы с дисками. `dirtied` значит, что ваш запрос должен был "подчищать" за другими запросами, проставля hint bits в записях. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 10:01 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm Не поверю, что чтобы прочитать 90000 строк из индекса, понадобится 365 секунд: если базе придется читать 90000 строк из маленькой таблички на 90 000--900 000 строк, то она просто забьёт на индексы и прочитает табличку последовательным доступом. т.е. относительно быстро. и отфильтрует. если же ей придется читать 90000 "по индексу" (из большой реально таблички, которую последовательно читать дорого) -- то это будет уже произвольный доступ. и , в случае механики, "чюдес не бываит" -- вряд ли блоки окажутся расположены так удачно, что затраты на полоборота диска куда--то все пропадут. только если только что что--то типа "кластер" было вдоль этого индекса сказано. и выборка подряд вдоль кластерного индекса. ну и если записей на блок много приходится и коэффициент перекрытия случится удачный (т.е. придется читать физически много меньше 90000 блоков)-- случится экономия в числе доступов (позиционировании головы). к тому же "по индексу", но "с доступом к самим записям" -- это несколько дороже, чем "только по индексу" -- там как бе 2 отдельные физические реляции получаются. и к обеим -- физически доступаться. зы. скоро обещают x--память, или как её -- скоро про механический доступ можно будет не вспоминать ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 10:36 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, База читает не по-строчно, а по-блочно. Было `read=275479` произвольных обращений к диску. Чтобы точно знать время IO операций, можно включить `track_io_timing=on`, тогда в плане будет видно реальное время работы с дисками. `dirtied` значит, что ваш запрос должен был "подчищать" за другими запросами, проставля hint bits в записях. Вот второй раз делаю этот же запрос: Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Откуда щас dirtied взялись? Это данные за вчера и апдейтов по ним не бывает. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 10:36 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqmaxxstormНе поверю, что чтобы прочитать 90000 строк из индекса, понадобится 365 секунд: если базе придется читать 90000 строк из маленькой таблички на 90 000--900 000 строк, то она просто забьёт на индексы и прочитает табличку последовательным доступом. т.е. относительно быстро. и отфильтрует. если же ей придется читать 90000 "по индексу" (из большой реально таблички, которую последовательно читать дорого) -- то это будет уже произвольный доступ. и , в случае механики, "чюдес не бываит" -- вряд ли блоки окажутся расположены так удачно, что затраты на полоборота диска куда--то все пропадут. только если только что что--то типа "кластер" было вдоль этого индекса сказано. и выборка подряд вдоль кластерного индекса. ну и если записей на блок много приходится и коэффициент перекрытия случится удачный (т.е. придется читать физически много меньше 90000 блоков)-- случится экономия в числе доступов (позиционировании головы). к тому же "по индексу", но "с доступом к самим записям" -- это несколько дороже, чем "только по индексу" -- там как бе 2 отдельные физические реляции получаются. и к обеим -- физически доступаться. зы. скоро обещают x--память, или как её -- скоро про механический доступ можно будет не вспоминать Делаю тот же запрос на тестовом сервере: Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Разница в скорости на 2 порядка. Разница в количестве записей 1:1.5, к тому же на тестовом сервере диски старые и медленные. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 10:53 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm Вот второй раз делаю этот же запрос: Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
maxxstorm<> Делаю тот же запрос на тестовом сервере: Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Разница в скорости на 2 порядка. Разница в количестве записей 1:1.5, к тому же на тестовом сервере диски старые и медленные. читать ещё не научили ? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 11:13 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqmaxxstormВот второй раз делаю этот же запрос: Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
maxxstorm<> Делаю тот же запрос на тестовом сервере: Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
Разница в скорости на 2 порядка. Разница в количестве записей 1:1.5, к тому же на тестовом сервере диски старые и медленные. читать ещё не научили ? Туплю чот. Как я понимаю, отца русской демократии спасет только SSD? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 14:01 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, Ну... SSD оно всегда хорошо. Но у меня есть мысль, что у вас могут быть распухшие таблицы и/или индексы. Там много UPDATE/DELETE операций? Можно сделать идентичный существующему индекс с другим именем и сравнить размеры. Можно таблицы "пожать", и индексы тогда точно надо будет перестроить. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 15:33 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, Ну... SSD оно всегда хорошо. Но у меня есть мысль, что у вас могут быть распухшие таблицы и/или индексы. Там много UPDATE/DELETE операций? Можно сделать идентичный существующему индекс с другим именем и сравнить размеры. Можно таблицы "пожать", и индексы тогда точно надо будет перестроить. 2-3млн инсертов + 200к делетов в сутки ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 15:38 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, А настройки autovcauum-а наверно умолчательные, да? Код: sql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 15:41 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, А настройки autovcauum-а наверно умолчательные, да? Код: sql 1.
Настойки по умолчанию, но почему то автовакуум не отрабатывает. Мы запускаем вручную vacuum analyze. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 15:42 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7.
Код: sql 1. 2.
... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 15:45 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm2-3млн инсертов + 200к делетов в сутки смутно кажется, что уместно будет пофантазировать на тему партицирования и, возможно, принудительной ротации/фриза хвостов. (если данные "в прошлое" могут торчать долго). но пока физ--смысл вашей кухни мне не настолько ясен, чтобы тут что--то советовать наверняка. -- партицирование всё сильно усложнит планировщику. а тем более -- sql--деву. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2016, 17:06 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Сравниваю с аналогичным запросом из другой бд(размер 50гб): Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
9 секунд и 428234 обращенй к диску. Делаю аналочичный запрос в свою таблицу(размер бд 150гб): Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Почему кост в 25 раз больше? Ведь количество записей одного порядка(11 и 15 млн соответственно) ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 11:41 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, 1. покажите Код: sql 1. 2. 3. 4. 5. 6.
с обеих; сравните попунктно. и по мелочи : 2. при расчете коста использовано 17 и 11 лямов -- по ожиданиям, а не по факту. (мелочь, а поправочка) 3. операции разные. (хотя и не настолько) ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 12:03 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqmaxxstorm, 1. покажите Код: sql 1. 2. 3. 4. 5. 6.
с обеих; сравните попунктно. и по мелочи : 2. при расчете коста использовано 17 и 11 лямов -- по ожиданиям, а не по факту. (мелочь, а поправочка) 3. операции разные. (хотя и не настолько) Абсолютно одинаковые дефолтные значения Код: sql 1. 2. 3. 4. 5.
Разные операция в смысле seq scan и index scan? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 12:07 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormРазные операция в смысле seq scan и index scan?а что, по буквам названия совпадают, чоль ? хотя почему подавлено сравнение со сек--сканом для вас -- не понял. думаю у вас какие--то енейблы отключены (что дает разовую прибавку к косту в 10 ярдов) посмотрите Код: sql 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 12:19 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, Львиную долю в цене составляет обращение к буферам. Если размер базы в 3 раза больше, то это имеет значение. Для маленькой базы у вас: Код: sql 1. 2. 3.
Для большой: Код: sql 1. 2. 3. 4.
Кол-во обращений надо считать общее, а не только `read`. И общее кол-во обращений во 2-м случае на порядок больше, ибо это проход по индексу, произвольный доступ. Да ещё с переодическим "подглядыванием" в кучу. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 12:22 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorov, там 2 вопроса -- 1. почему оно секвенс скан отбросило (который видимо задизейблен) 2. зачем для IOS БЕЗ УСЛОВИЙ (т.е. по всем листам == по всем блокам индекса) рендом доступ ? ожидают очень плохую карту ? (можно ожидания где--то увидеть?). или индекс принципиально всегда так фрагментирован, что обязательно поблочный рендом доступ ? //и никогда и никак -- не прочитать одним куском ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 12:33 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqпосмотрите Код: sql 1. 2. 3. 4. 5.
Все настройки одинаковые: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 12:43 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Сделал на своей БД Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
4 миллиона обращений против 400к для первой ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 12:46 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwq, Вопросы интересные. 1. Тут надо у @maxxstorm спрость что происходит. Я бы пробовал включать-выключать разные `enabled_%` опции и сравнивать косты. Ещё было бы интересно увидеть размер таблицы и индексов в блоках и записях (relpages и reltuples) из `pg_class`, а также кол-во удалённых записей в `pg_stat_user_tables`. 2. Тут я не уверен, надо код смотреть или же гуглить. Мне думается, что ПЖ не умеет делать IndexFastFullScan (в терминах О), он читает листья в порядке индекса, следуя по ссылкам в служебной зоне страниц -- это и приводит к произвольному доступу. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 12:50 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, А много изменений в таблице? Может она у вас банально распухла? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 12:52 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, А много изменений в таблице? Может она у вас банально распухла? апдейты редко бывают, автоваккум включен вроде, отрабатывает каждый день. Как определить, что распухла? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 12:53 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorov, там разница в буферах секскана -- тоже порядок. (при разнице ожиданий строк около 1,7) видимо очень пустые блоки приходится читать в количествах. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 13:00 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
qwwqvyegorov, там разница в буферах секскана -- тоже порядок. (при разнице ожиданий строк около 1,7) видимо очень пустые блоки приходится читать в количествах. vacuum full поможет? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 13:11 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, Для начала, посмотрите на вывод запроса (в `psql`): Код: sql 1.
Затем посмотреть на вывод такого запроса (осторожно, читает всю таблицу): Код: sql 1. 2.
... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 13:12 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormvacuum full поможет? Надо выяснить для начала что там такое. Если распухла, то: поможет надо пересмотреть настройки вакуума для конкретно этой таблицы также и на будущее ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 13:15 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, Для начала, посмотрите на вывод запроса (в `psql`): Код: sql 1.
Затем посмотреть на вывод такого запроса (осторожно, читает всю таблицу): Код: sql 1. 2.
Первый: relid | 16599 Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 13:35 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormСравниваю с аналогичным запросом из другой бд(размер 50гб): Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
9 секунд и 428234 обращенй к диску. Делаю аналочичный запрос в свою таблицу(размер бд 150гб): Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Почему кост в 25 раз больше? Ведь количество записей одного порядка(11 и 15 млн соответственно) А почему мы литры (sources_article) с километрами (san_material) сравниваем?.. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 14:37 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovА почему мы литры (sources_article) с километрами (san_material) сравниваем?.. Примерно одинаковые таблицы, одна и та же сущность. Просто удивила такая разница в скорости. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 14:39 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormvyegorovА почему мы литры (sources_article) с километрами (san_material) сравниваем?.. Примерно одинаковые таблицы, одна и та же сущность. Просто удивила такая разница в скорости. Я бы track_io_timing в базе бы включил для начала. С очень высокой вероятностью у вас время уходит на случайный ввод-вывод на IOS. -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 14:53 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Maxim BogukЯ бы track_io_timing в базе бы включил для начала. С очень высокой вероятностью у вас время уходит на случайный ввод-вывод на IOS. -- Maxim Boguk www.postgresql-consulting.ru Включил: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 15:05 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormvyegorovА почему мы литры (sources_article) с километрами (san_material) сравниваем?.. Примерно одинаковые таблицы, одна и та же сущность. Просто удивила такая разница в скорости. сущность могабыть одна, а вот ширина записи может разниться на порядок. особенно -- если где--то полно дроппед колумн с данными нагенерячено упор[от]ным трудом "оптимизатора--исследователя". и кол--во записей / на блок, как следствие, может отличаццо примерно в то же число раз. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 15:43 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstormMaxim BogukЯ бы track_io_timing в базе бы включил для начала. С очень высокой вероятностью у вас время уходит на случайный ввод-вывод на IOS. -- Maxim Boguk www.postgresql-consulting.ru Включил: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Ну вот вам и ответ. Как я и говорил - время на IO уходит. Скорее всего настройки seq_page_cost/random_page_cost/effective_cache_size не соответствуют реальности имеющейся дисковой системы. А какой размер таблицы и размер индекса (san_material_pkey) у вас? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 16:20 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Maxim BogukА какой размер таблицы и размер индекса (san_material_pkey) у вас? Таблица 17гб, индекс 363мб ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 16:34 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Maxim BogukНу вот вам и ответ. как бы помяхше , мммм... на что именно ответ ? аффтар какбе сегодня интересовался разностью костов на , с его т.з, почти одинаковых таблах. так вы утверждаете -- что вот это вот -- ответ про причину разности костов ? мммм ? как грицца -- два дебила -- это сила. продолжайте, очень интересно простите, если кого обидел, ага ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 17:01 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, `effective_cache_size` какой у вас? и также какое кол-во RAM-а, шареных? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 17:17 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, `effective_cache_size` какой у вас? и также какое кол-во RAM-а, шареных? effective_cache_size 15GB RAM 32GB shared_buffers 16GB ... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 17:18 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, А покажите вывод таких вот команд (для сравнения): Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
... |
|||
:
Нравится:
Не нравится:
|
|||
28.12.2016, 17:49 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
vyegorovmaxxstorm, А покажите вывод таких вот команд (для сравнения): Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Код: sql 1. 2. 3. 4. 5. 6. 7.
Код: sql 1. 2. 3. 4. 5. 6.
Код: sql 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
29.12.2016, 09:01 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, Значит база правильно IOS выбирает у вас (он быстрее даже когда часть данных с диска читается). seq scan сильно медленее у вас. А для запроса с public.sources_article - это на том же оборудовании делалось? Или это другой физический сервер? Так как сейчас мне кажется что сервер где "Сравниваю с аналогичным запросом из другой бд(размер 50гб):" он сильно другой по конфигурации. -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
29.12.2016, 09:24 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Maxim Bogukmaxxstorm, А для запроса с public.sources_article - это на том же оборудовании делалось? Или это другой физический сервер? то, что сек-скан сосет -- показано выше на отдизейбленном индекс скане. важно, что планер при одинаковых костах (т.е. мат моделях физ. состояния серверов), якобы на почти одинаковых табличках выбирает разные планы. видно, что буферов на "моём" кампутере больше почти на порядок (чем на эталонном). т.е. или записей на блок сильно меньше т.е. блоки пустые (что не так, если я правильно прочитал вывод), или записи (без тостов) сильно (почти на порядок) разной ширины. -- в итоге на в 1,7 раз отличающееся (по планам) число записей планируется в 20 раз больше костов (т.е., очевидно, блоков, т.к. ничего больше в последовательном чтении нет, а агрегат без дистинкта) -- какие--то такие выводы о том, почему "таблички одинаковы" а косты (абстрактные, на момент планирования) разные ... |
|||
:
Нравится:
Не нравится:
|
|||
29.12.2016, 10:24 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
maxxstorm, Для полноты картины, приведите выхлоп тех же запросов для таблицы `sources_article`. Я подозреваю, что эта таблице будет "уже", т.е. не будет разности в 50 раз между размером таблицы и её ПК. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.12.2016, 12:41 |
|
Тяжелый запрос к связанным таблицам
|
|||
---|---|---|---|
#18+
Вы были правы, таблица не та) Очень похожи названия, смотрю в структуру одной, а зпрос делаю из другой Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
... |
|||
:
Нравится:
Не нравится:
|
|||
29.12.2016, 12:48 |
|
|
start [/forum/search_topic.php?author=%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D1%82%D0%B0%D0%B2%D1%8C&author_mode=last_posts&do_search=1]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
64ms |
get topic data: |
12ms |
get forum data: |
2ms |
get page messages: |
145ms |
get tp. blocked users: |
2ms |
others: | 1870ms |
total: | 2148ms |
0 / 0 |