|
|
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Приветствую, посоветуйте как оптимизировать запрос вида: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Группировка вместо distinct по сути ничего не дает. Анализатор выдает аналогичный план. Индексы есть. В результате дофига записей сканируется - овер 2 млн. А возвращается - три. План запроса : автор"Sort (cost=115384.17..115384.19 rows=7 width=149)" " Sort Key: op_class.id" " -> HashAggregate (cost=115384.01..115384.08 rows=7 width=149)" " -> Nested Loop (cost=0.00..114712.66 rows=134269 width=149)" " Join Filter: (dict_operator_class_rel.class = op_class.id)" " -> Nested Loop (cost=0.00..100613.33 rows=134269 width=4)" " Join Filter: (dict_operator.id = dict_operator_class_rel.operator)" " -> Nested Loop (cost=0.00..85348.00 rows=26155 width=8)" " -> Nested Loop (cost=0.00..75498.78 rows=34780 width=4)" " -> Seq Scan on tp_published_hotline_ids ids (cost=0.00..536.40 rows=34940 width=4)" " -> Index Scan using pk_ti_operator_hotline on ti_operator_hotline (cost=0.00..2.14 rows=1 width=8)" " Index Cond: (id = ids.id)" " Filter: (NOT trash)" " -> Index Scan using pk_dict_operator on dict_operator (cost=0.00..0.27 rows=1 width=4)" " Index Cond: (id = ti_operator_hotline.operator)" " Filter: (NOT trash)" " -> Index Scan using pk_dict_operator_class_rel on dict_operator_class_rel (cost=0.00..0.50 rows=7 width=8)" " Index Cond: (operator = ti_operator_hotline.operator)" " Filter: (NOT trash)" " -> Materialize (cost=0.00..1.10 rows=7 width=149)" " -> Seq Scan on dict_operator_class op_class (cost=0.00..1.07 rows=7 width=149)" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2014, 12:49:02 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
1. Статистика нет - обновите. 2. Коды вьюх где? 3. LEFT JOIN "dict"."vw_dict_operator" AS "op" ON op.id = self.operator лишний в запросе - можно выкинуть ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2014, 13:38:08 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2014, 14:50:44 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Ivan Durak1. Статистика нет - обновите. 2. Коды вьюх где? 3. LEFT JOIN "dict"."vw_dict_operator" AS "op" ON op.id = self.operator лишний в запросе - можно выкинуть Да, про статистику не подумал, спасибо. Сделаю, отпишусь. Про LEFT JOIN - запрос динамически строится поэтому надо будет проанализировать этот нюанс - можно ли выбросить. LeXa NalBat, спасибо, этот запрос ускорил выполнение > чем в 2 раза. Пока конечно все равно дорогой. > 2 секунд. Вопрос сразу - в чем профит? Мануал пишет что авторThis simple example is like an inner join on col2, but it produces at most one output row for each tab1 row, even if there are several matching tab2 rows я так понимаю здесь выигрыш именно за счет того что одна строка выбирается и отбрасывается дальнейшая проверка? автор"Sort (cost=98097.67..98097.69 rows=6 width=149)" " Sort Key: op_class.id" " -> Nested Loop (cost=98096.42..98097.59 rows=6 width=149)" " -> HashAggregate (cost=98096.42..98096.46 rows=4 width=4)" " -> Nested Loop (cost=0.00..95404.26 rows=1076866 width=4)" " -> Nested Loop (cost=0.00..75632.68 rows=34923 width=4)" " -> Seq Scan on tp_published_hotline_ids ids (cost=0.00..537.83 rows=35083 width=4)" " -> Index Scan using pk_ti_operator_hotline on ti_operator_hotline (cost=0.00..2.13 rows=1 width=8)" " Index Cond: (id = ids.id)" " Filter: (NOT trash)" " -> Index Scan using pk_dict_operator_class_rel on dict_operator_class_rel (cost=0.00..0.50 rows=7 width=8)" " Index Cond: (operator = ti_operator_hotline.operator)" " Filter: (NOT trash)" " -> Index Scan using pk_dict_operator_class on dict_operator_class op_class (cost=0.00..0.27 rows=1 width=149)" " Index Cond: (id = dict_operator_class_rel.class)" Думаю добавить индекс для op_class_rel.class - оказывается его нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2014, 18:59:45 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
usver_dcIvan Durak1. Статистика нет - обновите. 2. Коды вьюх где? 3. LEFT JOIN "dict"."vw_dict_operator" AS "op" ON op.id = self.operator лишний в запросе - можно выкинуть Да, про статистику не подумал, спасибо. Сделаю, отпишусь. Про LEFT JOIN - запрос динамически строится поэтому надо будет проанализировать этот нюанс - можно ли выбросить. LeXa NalBat, спасибо, этот запрос ускорил выполнение > чем в 2 раза. Пока конечно все равно дорогой. > 2 секунд. Вопрос сразу - в чем профит? Мануал пишет что авторThis simple example is like an inner join on col2, but it produces at most one output row for each tab1 row, even if there are several matching tab2 rows я так понимаю здесь выигрыш именно за счет того что одна строка выбирается и отбрасывается дальнейшая проверка? автор"Sort (cost=98097.67..98097.69 rows=6 width=149)" " Sort Key: op_class.id" " -> Nested Loop (cost=98096.42..98097.59 rows=6 width=149)" " -> HashAggregate (cost=98096.42..98096.46 rows=4 width=4)" " -> Nested Loop (cost=0.00..95404.26 rows=1076866 width=4)" " -> Nested Loop (cost=0.00..75632.68 rows=34923 width=4)" " -> Seq Scan on tp_published_hotline_ids ids (cost=0.00..537.83 rows=35083 width=4)" " -> Index Scan using pk_ti_operator_hotline on ti_operator_hotline (cost=0.00..2.13 rows=1 width=8)" " Index Cond: (id = ids.id)" " Filter: (NOT trash)" " -> Index Scan using pk_dict_operator_class_rel on dict_operator_class_rel (cost=0.00..0.50 rows=7 width=8)" " Index Cond: (operator = ti_operator_hotline.operator)" " Filter: (NOT trash)" " -> Index Scan using pk_dict_operator_class on dict_operator_class op_class (cost=0.00..0.27 rows=1 width=149)" " Index Cond: (id = dict_operator_class_rel.class)" Думаю добавить индекс для op_class_rel.class - оказывается его нет. 1)приведите результаты explain analyze а не explain тогда можно будет понять где время тратится 2)есть ли индекс по "turpoisk"."vw_tp_published_hotline"(operator) 3)а какая у вас версия базы? 4)какие стоят значения random_page_cost и seq_page_cost PS: в общем explain без analyze не дает много пищи для размышлений о оптимизации PPS: профит в том что не образуется дублей которые приходится потом долго и упорно удалять -- postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2014, 19:24:34 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Maxim Boguk1)приведите результаты explain analyze а не explain тогда можно будет понять где время тратится 2)есть ли индекс по "turpoisk"."vw_tp_published_hotline"(operator) 3)а какая у вас версия базы? 4)какие стоят значения random_page_cost и seq_page_cost PS: в общем explain без analyze не дает много пищи для размышлений о оптимизации PPS: профит в том что не образуется дублей которые приходится потом долго и упорно удалять -- postgresql-consulting.ru Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. turpoisk.vw_tp_published_hotline Код: plsql 1. 2. 3. 4. 5. 6. 7. 2) Индекс на operator есть 3) Версия 9.2 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2014, 10:23:02 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
31к индекс сканов это многовато. Надо попробовать без лупа ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2014, 12:58:40 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Ivan Durak31к индекс сканов это многовато. Надо попробовать без лупа Каким образом? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2014, 13:09:58 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
usver_dc, А сколько всего у вас записей в "dict"."dict_operator_class" ? так как проблема вашего запроса в том что автор" -> HashAggregate (cost=94012.08..94012.12 rows=4 width=4) (actual time=14637.016..14637.022 rows=3 loops=1)" " -> Nested Loop (cost=0.00..91637.15 rows=949970 width=4) (actual time=0.044..11363.205 rows=2064900 loops=1)" 2M записей схлопываются в 3 записи... попробуйте вот что: в части автор "turpoisk"."vw_tp_published_hotline" AS "self" LEFT JOIN "dict"."vw_dict_operator_class_rel" AS "op_class_rel" ON self.operator = op_class_rel.operator замените LEFT JOIN на JOIN так как учитывая то что дальше идет Код: plsql 1. от LEFT JOIN тут один вред и путаница для планировщика... есть ли индексы на "dict"."vw_dict_operator_class_rel"(class) и на "turpoisk"."vw_tp_published_hotline"(operator) ? PS: я все больше склоняюсь к идее что проблема именно в вышеупомянутом LEFT JOIN ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2014, 13:34:26 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Maxim Bogukusver_dc, А сколько всего у вас записей в "dict"."dict_operator_class" ? так как проблема вашего запроса в том что автор" -> HashAggregate (cost=94012.08..94012.12 rows=4 width=4) (actual time=14637.016..14637.022 rows=3 loops=1)" " -> Nested Loop (cost=0.00..91637.15 rows=949970 width=4) (actual time=0.044..11363.205 rows=2064900 loops=1)" 2M записей схлопываются в 3 записи... попробуйте вот что: в части автор "turpoisk"."vw_tp_published_hotline" AS "self" LEFT JOIN "dict"."vw_dict_operator_class_rel" AS "op_class_rel" ON self.operator = op_class_rel.operator замените LEFT JOIN на JOIN так как учитывая то что дальше идет Код: plsql 1. от LEFT JOIN тут один вред и путаница для планировщика... есть ли индексы на "dict"."vw_dict_operator_class_rel"(class) и на "turpoisk"."vw_tp_published_hotline"(operator) ? PS: я все больше склоняюсь к идее что проблема именно в вышеупомянутом LEFT JOIN Насчет left join тоже заметил и заменял на join, но эффекта не дала замена. на operator есть, на class не было индекса. Об этом я упоминал выше. Заявка в группу бд висит. Посмотрим как поможет. на данный момент какие правки внедрены: Изменен запрос + заявка на БД: авторvacuum analyze ti.ti_operator_hotline; vacuum analyze turpoisk.tp_published_hotline_ids; -- Index: dict.idx_dict_operator_class_rel_class -- DROP INDEX dict.idx_dict_operator_class_rel_class; CREATE INDEX idx_dict_operator_class_rel_class ON dict.dict_operator_class_rel USING btree (class ); -- Index: dict.idx_dict_operator_class_rel_operator -- DROP INDEX dict.idx_dict_operator_class_rel_operator; CREATE INDEX idx_dict_operator_class_rel_operator ON dict.dict_operator_class_rel USING btree (operator ); В понедельник отпишусь о результате. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2014, 13:47:12 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
В общем пока результат не очень. С 6-ти секунд опустились до 2-х. Это очень много. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2014, 11:20:07 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
usver_dcВ общем пока результат не очень. С 6-ти секунд опустились до 2-х. Это очень много. Приведите на всякий случай: 1)А сколько всего у вас записей в "dict"."dict_operator_class" (это важно). 2)приведите результат (с JOIN внутри exists вместо LEFT JOIN) Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2014, 12:25:34 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Maxim Boguk, Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Код: plsql 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. Код: plsql 1. 7 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2014, 12:53:03 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
usver_dc, Ok тогда начнем постадийно решать проблему (полезный топик получится)... начнем с максимально упрощенной версии c выкинутой частью функционала: что говорит: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ? --Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2014, 13:38:39 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Maxim Bogukusver_dc, Ok тогда начнем постадийно решать проблему (полезный топик получится)... начнем с максимально упрощенной версии c выкинутой частью функционала: что говорит: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ? --Maxim Boguk www.postgresql-consulting.ru Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2014, 13:53:35 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
usver_dc, так уже понятнее... а приведите \d+ "dict"."vw_dict_operator_class_rel" \d+ dict.dict_operator_class_rel \d+ dict.dict_operator_class у меня ощущение что или индексы пропущены всетаки или типы не совпадают или в определении VIEW у вас косяк какой то... --Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2014, 13:59:36 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Код: plsql 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. Maxim Bogukusver_dc, так уже понятнее... а приведите \d+ "dict"."vw_dict_operator_class_rel" \d+ dict.dict_operator_class_rel \d+ dict.dict_operator_class у меня ощущение что или индексы пропущены всетаки или типы не совпадают или в определении VIEW у вас косяк какой то... --Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2014, 14:23:34 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
М/б индекс по trash добавить? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2014, 14:27:51 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
добавьте LIMIT 1 в подзапрос EXISTS ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2014, 16:13:26 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat, Поднялось до 6 секунд Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Код: plsql 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2014, 16:33:49 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
usver_dc, Так... хорошо... 1) Код: plsql 1. 2) show random_page_cost; show seq_page_cost; 3) сделайте индекс по Код: plaintext 4)после 3 выполните Код: plaintext Код: plaintext 5)сдетайте еще раз Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. В общем если кратко задача избавится от seq_scan в EXISTS, после этого скорее всего и основной запрос ускорится. --Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2014, 16:54:32 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Maxim Bogukusver_dc, Так... хорошо... 1) Код: plsql 1. 2) show random_page_cost; show seq_page_cost; 3) сделайте индекс по Код: plaintext 4)после 3 выполните Код: plaintext Код: plaintext 5)сдетайте еще раз Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. В общем если кратко задача избавится от seq_scan в EXISTS, после этого скорее всего и основной запрос ускорится. --Maxim Boguk www.postgresql-consulting.ru 1. Не понял, а зачем оно Вам? Тут же и так ясно, что будет скан по таблице. Код: plsql 1. 2. 2) show random_page_cost; 4 show seq_page_cost; 1 5) С тестовой бд (количество данных от релиза не сильно разнится): Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. ЗЫ может оптимизатор решил что ему быстрее пройти по таблице чем индекс юзать... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2014, 18:32:22 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Проблема в том что 31 тысяча индекс сиков по таблице с 9 тысячами записей - это ПЛОХО! ------------------------------------------- 1. Попробуй "turpoisk"."vw_tp_published_hotline" AS "self" заменить на ti_operator_hotline если логика это позволяет!!! 2. Также независимо от #1 надо на ti_operator_hotline него индекс по полю operator. И ждем MERGE JOIN. Типа: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2014, 12:06:56 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
usver_dc, автор 5) С тестовой бд (количество данных от релиза не сильно разнится): "Nested Loop (cost=191.84..193.01 rows=6 width=6) (actual time=4.600..4.621 rows=5 loops=1)" " Output: op_class.id, op_class.name" " -> HashAggregate (cost=191.84..191.88 rows=4 width=4) (actual time=4.467..4.469 rows=5 loops=1)" " Output: dict_operator_class_rel.class" " -> Seq Scan on dict.dict_operator_class_rel (cost=0.00..178.82 rows=5210 width=4) (actual time=0.008..2.553 rows=5210 loops=1)" " Output: dict_operator_class_rel.operator, dict_operator_class_rel.country, dict_operator_class_rel.class, dict_operator_class_rel.updated, dict_operator_class_rel.trash, dict_operator_class_rel.date_create" " Filter: (NOT dict_operator_class_rel.trash)" " Rows Removed by Filter: 4472" " -> Index Scan using pk_dict_operator_class on dict.dict_operator_class op_class (cost=0.00..0.27 rows=1 width=6) (actual time=0.027..0.028 rows=1 loops=5)" " Output: op_class.id, op_class.name, op_class.info, op_class.active, op_class.trash, op_class.updated, op_class.weight" " Index Cond: (op_class.id = dict_operator_class_rel.class)" "Total runtime: 4.761 ms" Очень странно... а если сделать set enable_seqscan to 0; и повторить explain и если будет hash join или merge join сделать set enable_hashjoin to 0; set enable_mergejoin to 0; Я к чему веду - если в таблице dict.dict_operator_class 7 записей то это запрос должен выполнятся через nested loop по таблице dict.dict_operator_class_rel и seq scan по dict.dict_operator_class что на выходе даст всего 7 index scan по dict.dict_operator_class_rel что и будет самым быстрым методом выполнения этого запроса, и очень странно что база сама этого не делает. PS: я бы с настройками планировщика бы поигрался... особенно в сторону увеличения cpu_tuple_cost с 0.01 до 0.1 (чтобы оно меньше пыталось seq scan/merge join делать). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2014, 15:05:48 |
|
||
|
оптимизация запроса
|
|||
|---|---|---|---|
|
#18+
Код: sql 1. Это как писали выше имхо лишнее, Зачем делать LEFT JOIN если вы потом все равно делаете Код: sql 1. этим джойном вы уничтожаете разницу между LEFT и INNER "op_class_rel" ИМХО для начала переписать запрос Код: sql 1. 2. 3. 4. 5. 6. 7. и оптимизатору уже будет гораздо проще определиться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2014, 23:23:12 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=38638981&tid=1998683]: |
0ms |
get settings: |
5ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
302ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
62ms |
get tp. blocked users: |
1ms |
| others: | 197ms |
| total: | 603ms |

| 0 / 0 |
