|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
почему такой запрос: Код: sql 1.
работает 5379 ms, а такой запрос: Код: sql 1.
работает 3649 ms ? explain 1 Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
explain 2 Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
кстати, индекс на ts есть, но почему-то "Parallel Seq Scan"... ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2021, 16:38 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
бабушкин зайчик, я бы начал изучение вопрос с проверки следующих моментов: 1) выключил бы параллельное выполнение запросов и посмотрел бы на время выполнения запроса в 1 поток в обоих случаях причем раза по 3-4 обе версии чтобы посмотреть действительно ли результаты воспроизводимо отличаются в 1.5 раза если нет - то вопрос закрывается автоматически если же даже без параллельного выполнения запросов есть 1.5 разницы стабильной в скорости работы - тогда будем думать. 2)про почему seq scan: покажите что дает запрос Код: sql 1.
и Код: sql 1.
и тогда станет понятнее. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
02.05.2021, 19:27 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.05.2021, 22:59 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
Maxim Boguk 1) выключил бы параллельное выполнение запросов что именно и где надо выключить? ... |
|||
:
Нравится:
Не нравится:
|
|||
02.05.2021, 23:01 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
бабушкин зайчик, Потому что трунк мутит что-то с датой, а без него тупо сравнивается 2 лонга. На оракле такая же хрень у нас, трунк в запросы стараются не совать. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2021, 10:30 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
бабушкин зайчик Maxim Boguk 1) выключил бы параллельное выполнение запросов что именно и где надо выключить? set max_parallel_workers_per_gather to 0; explain (analyze, costs, buffers, timing) ваши запросы (лучше несколько раз выполнять). Про seq scan - у вас больше 5% таблицы вычитывается в результат запроса... сильно не факт что index scan будет быстрее. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2021, 12:42 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
crutchmaster бабушкин зайчик, Потому что трунк мутит что-то с датой, а без него тупо сравнивается 2 лонга. На оракле такая же хрень у нас, трунк в запросы стараются не совать. так он же 1 раз всего мутит... Maxim Boguk Про seq scan - у вас больше 5% таблицы вычитывается в результат запроса... сильно не факт что index scan будет быстрее. разве там не 30% нужно, чтобы seq scan был? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2021, 13:58 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
бабушкин зайчик Maxim Boguk Про seq scan - у вас больше 5% таблицы вычитывается в результат запроса... сильно не факт что index scan будет быстрее. разве там не 30% нужно, чтобы seq scan был? Зависит от настроек базы и параметров оборудования... на холодную на механических дисках даже 1% был/есть быстрее seq scan вычитывать. 30% почти всегда будет дешевле seq scan (и даже на 10%). -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2021, 17:48 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
бабушкин зайчик так он же 1 раз всего мутит. Вот я тоже так думал, но походу всё сложнее. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2021, 19:05 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
crutchmaster бабушкин зайчик так он же 1 раз всего мутит. Вот я тоже так думал, но походу всё сложнее. Похоже, что выражение date_trunc('quarter', CURRENT_DATE) вычисляется не один раз, а для каждой строки запроса. Начальный запрос: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Если функцию CURRENT_DATE заменить на константу, то запрос ускоряется: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
А если вызов date_trunc вложить в подзапрос, то ускоряется еще больше. Подзапрос в скобках (SELECT ..) на месте скалярного выражения, выполняется один раз на запрос (узел initplan): Код: 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 версиях. Каждый запрос выполнял 4-5 раз, для получения стабильного времени выполнения. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.05.2021, 13:45 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
Павел Лузанов, Ну хоть кто то не ленивый на этом форуме. Спасибо большое. Еще бы понять почему так, volatile функций я не смог найти в цепочке. Жалко нельзя сделать set track_functions to 'system' для анализа какие системные функции вызывались в запросе и сколько. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
05.05.2021, 14:23 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
А если с now() попробовать? Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95.
... |
|||
:
Нравится:
Не нравится:
|
|||
05.05.2021, 16:02 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
CURRENT_DATE или now() - значение не имеет а вот подзапрос имеет, даёт почти такой же результат, как константа хотел бы я посмотреть на код этой замечательной функции... ... |
|||
:
Нравится:
Не нравится:
|
|||
05.05.2021, 17:00 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
бабушкин зайчик хотел бы я посмотреть на код этой замечательной функции... Могу научить: берём в psql \sf date_trunc(text, timestamp) затем ищем по исходникам git grep timestamp_trunc находим https://github.com/postgres/postgres/blob/REL_13_STABLE/src/backend/utils/adt/timestamp.c#L3815 ... |
|||
:
Нравится:
Не нравится:
|
|||
05.05.2021, 17:14 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
Maxim Boguk Еще бы понять почему так, volatile функций я не смог найти в цепочке. Разная скорость получается не только по сравнению date_trunc с константой, но и с другой stable функцией - now. Но что самое интересное, дело вовсе не в volatile. Любая из этих stable функций выполняется для каждой строки запроса. Просто now умеет кешировать свой результат, а date_trunc каждый раз выполняет разбор и усечение даты, на что время и уходит. Рекомендация - использовать скалярные подзапросы (SELECT ..) или CTE. Подробности здесь . ... |
|||
:
Нравится:
Не нравится:
|
|||
05.05.2021, 17:42 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
Melkij бабушкин зайчик хотел бы я посмотреть на код этой замечательной функции... Могу научить: берём в psql \sf date_trunc(text, timestamp) затем ищем по исходникам git grep timestamp_trunc находим https://github.com/postgres/postgres/blob/REL_13_STABLE/src/backend/utils/adt/timestamp.c#L3815 очевидно копать придётся глубже главный вопрос - кто додумался простую константу высчитывать для каждой строки ... |
|||
:
Нравится:
Не нравится:
|
|||
05.05.2021, 18:21 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
Павел Лузанов Подробности здесь . Всё оказалось интереснее. Я для себя сделал следующие выводы. Особенности выполнения любых(пользовательских, системных) STABLE функций в запросах вида: Код: sql 1.
Отметка STABLE не гарантирует того, что функция будет выполнена только один раз. В случае последовательного сканирования таблицы, функция выполняется для каждой строки запроса. Если в таблице есть индекс по столбцу col, то планировщик может выбрать сканирование индекса. В этом случае отметка STABLE дает право вычислить значение функции один раз и использовать это значение для поиска в индексе. В случае последовательного сканирования, в стоимость плана помимо прочего входит стоимость функции умноженная на количество строк. Для пользовательских функций стоимость по умолчанию равна 100. Возможно это значение стоит изменить для более адекватной оценки. Уменьшение стоимости функции будет приводить к снижению стоимости последовательного сканирования таблицы и наоборот. Уточнение оценки стоимости функции даст возможность планировщику более точно сделать выбор между последовательным сканированием и сканированием индекса. Если последовательное сканирование предпочтительнее, то избежать многократного выполнения функции можно при помощи материализации результата функции. Есть два способа материализовать результат: скалярный подзапрос и CTE. Код: sql 1.
Код: sql 1.
В любом случае у планировщика нет возможности использовать результат выполнения функции для построения плана. Поэтому не получится использовать статистику по столбцу t.col для выбора оптимального плана. При выборе плана будет использоваться общий алгоритм. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2021, 10:49 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
Павел Лузанов Похоже, что выражение date_trunc('quarter', CURRENT_DATE) вычисляется не один раз, а для каждой строки запроса. Это понятно, но какого хрена оно вычисляется каждый раз, если, вроде как, очевидно, что константное? Походу никто просто не стал греть себе голову тем, константное оно там или нет. ЕМПНИ в mysql такого не было, там в where можно было вводить переменные и всё срабатывало один раз. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2021, 11:28 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
да постгря не первый раз удивляет есть там неочевидное ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2021, 12:50 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
это ппц просто, надо снаружи БД (в PHP) пересчитать в константу, а её уже вставлять в запрос вместо date_trunc(), потому что SELECT date_trunc() тоже не спасает и даже если в WITH date_trunc() засунуть, всё равно тормоза... ...и вот так тоже: CURRENT_DATE - '64 day'::interval Только константа не тормозит. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2021, 15:32 |
|
почему date_trunc() в 1.5 раза медленнее?
|
|||
---|---|---|---|
#18+
хм, а если '2021-04-01 00:00:00' увеличить до '2021-03-01', то опять те же тормоза... ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2021, 15:45 |
|
|
start [/forum/topic.php?fid=53&fpage=12&tid=1994042]: |
0ms |
get settings: |
11ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
27ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
56ms |
get tp. blocked users: |
2ms |
others: | 279ms |
total: | 413ms |
0 / 0 |