|
|
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
Всем привет. PostgreSQL 9.2.8 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit Имеется большая таблица hotcore.otahotel Это таблица - партицирована по неделям. в одной партиции около 67 млн. строк Агрегирую некоторые данные таким запросом: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. такой план: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. Можно как-то улучшить время выполнения. спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.08.2014, 18:05:26 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
Вот план в чуть более удобном виде . Таблица `otahotel_2014w32` холодная (`Buffers: shared hit=1101 read=47974`), сильно ли меняется время при повторном запуске запроса? Если заменить именованные подзапросы на обычные (избавиться от `WITH` конструкции), будет ли план лучше? Слияние циклами в #13 больно дорого выходит. Чтобы подобрать более вменяемый план, поиграйтесь с `enable_*` опциями на уровне сессии. Скажем, будет ли план лучше при Код: sql 1. ? Мне кажется тут хэширование будет быстрее... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.08.2014, 19:19:08 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
best_time, тут похоже поможет только кластеризация партиций otahotel по otahotel_id, чтобы с диска меньше читать. но другие запросы могут замедлиться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.08.2014, 21:55:10 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
best_time, Приведите план запроса (ну и результат): Код: sql 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.08.2014, 22:14:52 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
/\/\/\/\/\/\/\, Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. результат 65288691 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2014, 16:04:42 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
vyegorovТаблица `otahotel_2014w32` холодная (`Buffers: shared hit=1101 read=47974`), сильно ли меняется время при повторном запуске запроса? теплая работаем заметно лучше, но при работе в кеш она не попадает vyegorovЕсли заменить именованные подзапросы на обычные (избавиться от `WITH` конструкции), будет ли план лучше? Попробовал. Вроде получше. Почему? ) такой план (меняю id'шники, паритции - моделирую холодную работу Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. авторСлияние циклами в #13 больно дорого выходит. Чтобы подобрать более вменяемый план, поиграйтесь с `enable_*` опциями на уровне сессии. Скажем, будет ли план лучше при Код: sql 1. ? Код: sql 1. 2. это пробовал - иногда чуть лучше Alexiusbest_time, тут похоже поможет только кластеризация партиций otahotel по otahotel_id, чтобы с диска меньше читать. но другие запросы могут замедлиться. оставлю пока "про запас" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2014, 18:34:10 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
best_timevyegorovЕсли заменить именованные подзапросы на обычные (избавиться от `WITH` конструкции), будет ли план лучше? Попробовал. Вроде получше. Почему? Ничего в целом не поменялось. “Получше” потому, что `WITH` конструкции имеют защиту от оптимизаций. При переписывании с обычными подзапросами у оптимизатора развязаны руки на трансформацию запросов, проталкивание предикатов и другие плюшки. best_timevyegorovСлияние циклами в #13 больно дорого выходит. Чтобы подобрать более вменяемый план, поиграйтесь с `enable_*` опциями на уровне сессии. Скажем, будет ли план лучше при Код: sql 1. ? Код: sql 1. 2. это пробовал - иногда чуть лучше А были ли варианты когда Hash Join использовался? Можно пример? Ну а таблица остается “холодной” при использовании SeqScan из-за особенностей работы с кэшем. Чтобы избежать его “вымывания” для SeqScan-ов выделяется маленькая часть кэша, которая используется в цикле ( тут, стр. 10 ). И еще — что возвращает такой запрос? Код: sql 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 00:32:19 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
vyegorov, судя по запросу вы зря ударились оптимизировать джойн до свёртки похоже просто надо переписать на джойн после свёртки поскольку со стороны tt тянутся поля однозначно соответствующие tt.id будет свертка (агрегат) по полному скану -- что стоит, как описал автор, 104027.062 ms (что вдвое быстрее) + джойн коротких таблиц. ------------------- если же автор хочет насладиться преимуществом limit 100, то ему вот это надо ускорять Код: sql 1. 2. 3. 4. -- расскажите нам, что это и зачем оно тут, если уже явно всё, какбе, отыскано "внутри", причем много дешевле: Код: sql 1. 2. 3. -- т.е. есть подозрение, что пройти рекурсивно по 100 id из tt "вручную" (в WITH RECURSIVE) будет много дешевле. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 10:56:05 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
ЗЫ, если лениво переписывать -- есть подозрение, что индекс типа otahotel_2014w32_otahotel_id_report_date_idx (otahotel_id,report_date) вправят оптимайзеру мозги взад, но надо проверять ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 11:04:26 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
--поправилvyegorov, судя по запросу вы зря ударились оптимизировать джойн до свёртки ------------------- если же автор хочет насладиться преимуществом limit 100, то ему вот это надо ускорять Код: sql 1. 2. 3. 4. Вот ради оптимизации `loops=100` и пытаюсь понять, почему оптимизатор выбирает цикл, а не хэш. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 11:19:01 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#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. 24. 25. 26. 27. 28. 29. Как-то так. Но выбор во временные данные 65 млн строк меня смущает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 11:24:33 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
vyegorov, не понял, зачем там хеш. тогда уж свернуть сначала, а потом джойнить. получите то, чего хотите, без затрат на джойн (это что, всю миллионную захешировать, потом поджойнить, и результат свернуть ? боец борется за разницу меж лямами [65288691, но последовательно] и килами [48394, но произвольно] ) -- тут интересно то, что эти записи (484) оптимайзер находит (внутри, по индексу) практически без затрат времени (пусть и лупнув 100) -- см. этап 18 плана по ссылке а затем (снаружи) зачем то делает над ними же 17. Bitmap Heap Scan on otahotel_2014w32 av но уже теряя кучу (втрое) времени Код: sql 1. 2. 3. 4. -- я не силён в таких тонкостях -- напрочь не понимаю, чем оно тут занимается. фильтровать оно могло и на проходе 18. считай бесплатно. PS -- если бы в 18 было написано IOS -- я бы хоть что-то понял ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 11:42:49 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
/\/\/\/\/\/\, не, я не про то. я про 2 абсолютно разные альтернативы 1. свернуть все 65 лямов на проходе (100 секунд --см выше), потом поджойниться - выиграем вполовину, но никак не больше или (совсем другое) 2. взять в CTE 100 id, и для каждого из них в конструкции with recursive взять свой агрегат (что оптимайзер [+-километр] и должен делать, но я как-то это плохо читаю). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 11:50:10 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
авторно уже теряя кучу (втрое в 30 -- 2400 vs 80) времени ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 12:00:20 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
--поправилvyegorov, не понял, зачем там хеш. тогда уж свернуть сначала, а потом джойнить. получите то, чего хотите, без затрат на джойн (это что, всю миллионную захешировать, потом поджойнить, и результат свернуть ? боец борется за разницу меж лямами [65288691, но последовательно] и килами [48394, но произвольно] ) Хэшируется меньшая сторона, потом делается проход по большей. В данном случае сделать хэш для 100 записей из подзапроса и потом один раз пройти SeqScan-ом по 67 лимонам мне кажется будет быстрым, в пределах тех же 100 секунд. Я вижу 2 причины почему не используется хэш: невозможно архитектурно (внутренние ограничения СУБД), но это гипотеза, точно не знаю что может быть такого; перекос в статистиках/недостаточный размер гистограммы. Тут можно что-то крутить. Что же касается “переписать” запрос — полностью согласен. Но хочется же разобраться в чем тут дело... --поправил-- тут интересно то, что эти записи (484) оптимайзер находит (внутри, по индексу) практически без затрат времени (пусть и лупнув 100) -- см. этап 18 плана по ссылке а затем (снаружи) зачем то делает над ними же 17. Bitmap Heap Scan on otahotel_2014w32 av но уже теряя кучу (втрое) времени Код: sql 1. 2. 3. 4. -- я не силён в таких тонкостях -- напрочь не понимаю, чем оно тут занимается. фильтровать оно могло и на проходе 18. считай бесплатно. PS -- если бы в 18 было написано IOS -- я бы хоть что-то понял Это особенности работы BitmapScan-а. Сначала он идет по индексу, но возвращает для каждого блока (8Кб) содержащего искомые значения 1, или 0 в противном случае. Понятно, что после этого надо прочитать такие блоки и вытащить из них записи. Потому и получается всегда 2 (и более) этапа: сначала несколько Bitmap Index Scan-ов; наложение битмапов если более 1 индекса на 1-м шаге; результирующий Bitmap Heap Scan. Смысл в том, что если несколько индексов реляции подпадают под предикаты, по ним всем делаются проходы (Bitmap Index Scan), затем полученные битмапы логически накладываются (BitmapAnd / BitmapOr) и только потом идет обращение к записям (Bitmap Heap Scan) — быстрее выходит. Для единственного индекса такой проход выбирается, если селективность не очень. Тут подробнее . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 12:10:40 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
vyegorov, 1. люди, пишущие pdf идут строго лесом. (я не типография) 2. т.е. вы хотите сказать, что 18 -- это реально IOS ? а потом BitmapOr с реальным произвольным доступом к 48000 записям (страницам) жрет 240 сек ? по ~5 ms на доступ? [200 в секунду -- 1200 в минуту - не маловато будет? или я где-то провираюсь ?) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 12:29:39 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
--поправилvyegorov, 1. люди, пишущие pdf идут строго лесом. (я не типография) 2. т.е. вы хотите сказать, что 18 -- это реально IOS ? а потом BitmapOr с реальным произвольным доступом к 48000 записям (страницам) жрет 240 сек ? по ~5 ms на доступ? [200 в секунду -- 12000 в минуту - не маловато будет? или я где-то провираюсь ?) бгг. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 12:35:10 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
там при ожиданиях много хуже 48к авторrows=3001390 оптимайзер пускается на NestedLoop -- имхо у ТС косты переставлены супротив дефолтных. или enable seqscan (и т.п.) в off-е ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 12:44:05 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
vyegorovИ еще — что возвращает такой запрос? Код: sql 1. 2. 3. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 13:52:40 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
best_time Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Я ожидал увидеть больше колонок: тыц . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 14:15:06 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
vyegorov, там 0 и NULL'ы - все равно важно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 14:51:38 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
vyegorov, могабыть оно слишком мало ожидает строк от tt ? Код: sql 1. 2. причем (что не очевидно, но вероятно) -- похоже geo.name можно извлечь уже в t коррелированным полем (или ТС ожидает там размножения имен ?) -- тогда оптимизатор будет знать, что предстоит искать в big table по 100 а не по 9 id-кам. но то, что оно планирует Nested Loop при ожидании 3001390 rows Код: sql 1. -- кажется сипанным. что то подкручено с cost-ами ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 15:14:16 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
best_time, SHOW random_page_cost ; ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 15:18:44 |
|
||
|
улучшить время выполнения
|
|||
|---|---|---|---|
|
#18+
best_timevyegorov, там 0 и NULL'ы - все равно важно? Хм, если там NULL-ы, то у меня вопросы: как статистики собираются в системе вообще? что выдаст такой запрос Код: sql 1. как изменится план после запуска следующих команд Код: sql 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2014, 15:22:14 |
|
||
|
|

start [/forum/topic.php?fid=53&fpage=124&tid=1998523]: |
0ms |
get settings: |
8ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
66ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
84ms |
get tp. blocked users: |
1ms |
| others: | 200ms |
| total: | 395ms |

| 0 / 0 |
