|
|
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#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. результат: Код: 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. 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. при Код: plsql 1. если Код: plsql 1. то для Код: plsql 1. 2. 3. 4. 5. 6. индексы не используются и время не изменяется, также на данный отрезок скрипта идет основная потеря времени(без него в 3-4 раза быстрее). Параметры таблицы(имя/кол-во строк/размер): Код: plaintext Код: plsql 1. 2. 3. 4. Некоторые параметры БД: Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.10.2014, 12:19:48 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
its_me, попробуйте добавить индекс (template_id, status_id) в таблицу a_v_card_test. Код: sql 1. 2. 3. планнер тут очень сильно ошибается в количестве строк, и из-за этого возможно не самый оптимальный план получается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.10.2014, 12:36:02 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
Alexius, 5+, видать неусмотрел я. Total time: 3с, Еще сократить можно интересно... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.10.2014, 12:45:10 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
its_me, наверняка можно, надо новый план смотреть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.10.2014, 12:49:07 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
Код: 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. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.10.2014, 14:13:51 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
its_me, хм, можно попробовать создать индекс в a_v_name_test на поле UPPER(av99.string_value) используя расширение pg_trgm . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.10.2014, 09:59:03 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
CREATE INDEX a_v_name_test_idx ON a_v_name_test USING gist (UPPER(string_value) gist_trgm_ops) ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.10.2014, 10:18:28 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
its_me, да. если запросы по этому полю селективные, то должно хватить. если attribute_code == 'NAME' всегда в этом запросе, то можно частичный индекс сделать по этому условию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.10.2014, 10:31:17 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
Код: plsql 1. Супер - в 10 раз, но возникала другая проблема если ввести например вместо AND UPPER(av99.string_value) like UPPER('%Администрация островского района%') вот это AND UPPER(av99.string_value) like UPPER('%гу%'), то он почему то не использует данный индекс а использует обычный по string_value. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.10.2014, 11:48:57 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
вот это использует: Код: plsql 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.10.2014, 11:51:07 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
Если убрать этот индекс, то делает по новому, но долго... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.10.2014, 11:55:28 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
its_me, естественно, запрос должен быть селективным чтобы индекс эффективно использовался. attribute_value_name_string_value_idx - этот индекс для данного запроса не оптимальный, поле string_value из него никогда не будет использоваться, можно его отсюда выкинуть (если другие запросы его не используют). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.10.2014, 12:40:39 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
а для "гу" можно что сделать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.10.2014, 14:15:04 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
Вообще чисто по плану, очевидно что правильный план должен сначала фильтровать a_v_card_test по Filter: ((status_id = ANY ('{4,7}'::numeric[])) AND (template_id = 222::numeric))" Получив 27 записей, а затем бежать index scan'ом по av99 и условию (c.card_id = av99.card_id) Получив 27 записей и потом уже фильтровать (av99.attribute_code IN ('NAME') AND ( av99.string_value IS NOT NULL) AND UPPER(av99.string_value) like UPPER('%Текст%') Получив 27 записей. Другое дело почему он так не делает. А не делает это потому что статистика у него идет в разнос, почему-то -> Seq Scan on a_v_card_test c (cost=10000000000.00..10000085000.20 rows=524880 width=17) (actual time=36.922..65.091 rows=27 loops=1)" " Filter: ((status_id = ANY ('{4,7}'::numeric[])) AND (template_id = 222::numeric))" " Buffers: shared hit=77127" он думает что с таким фильтром 524880 записей (может проблема в ANY, может статистика не обновлена, но похоже нужно смотреть на данные). А тут наоборот (хотя тут понятнее - LIKE всегда жесткий случай) -> Index Scan using a_v_attribute_code on a_v_name_test av99 (cost=0.43..225849.96 rows=278 width=6) (actual time=21.399..9579.397 rows=58 loops=1)" " Index Cond: ((attribute_code)::text = 'NAME'::text)" " Filter: ((string_value IS NOT NULL) AND (upper((string_value)::text) ~~ '%Текст%'::text))" " Rows Removed by Filter: 2819921" " Buffers: shared hit=72164" Кстати по card_id индексы есть? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.10.2014, 17:47:55 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
Nitro_Junkie, Хотя со вторым не такая большая ошибка. Там не сильное отличие. Проблема с первой частью, в которой она думает 580000 (индекс то по card_id у вас явно есть), и по этому не хочет index scan делать хотя надо бы. Попробуйте разбить на 2 запроса в одном из которых будет status = 4, а во втором status = 7, а потом UNION'ом соедините. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.10.2014, 17:59:58 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
Nitro_Junkie, Индекс по card_id везде есть, сами запросы неизменны(надо подстраиваться под них). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2014, 09:06:25 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
its_meNitro_Junkie, Индекс по card_id везде есть, сами запросы неизменны(надо подстраиваться под них). А по status_id и template_id ? Хотя корень проблемы конечно в неправильной статистике фильтра. А вы попробуйте сбоку запустить запрос с не IN (4,7) а просто status_id = 4. И попробуйте ALTER TABLE ... SET STATISTICS для status_id и template_id поставить 10000 (после чего ANALYZE только не забудьте выполнить) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2014, 09:41:30 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
Nitro_Junkie, Черт, смотрел на старый план. Но в новом все та же проблема. Попробуйте в принципе default_statistics_target увеличить. Но не поможет :( Проблема в том что в postgres нет cross-column статистики. И он тупо перемножает selectivity для template_id и status_id. А они у вас на самом деле сильно коррелированы. Без переписывания запроса без шансов. :( Да и с переписыванием в общем случае, единственное что можно делать "объединять" колонки в одну (ROW'ом или чем-то еще) и по ней join'ить (но это по сути ручное управление выполнением join'ов). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2014, 09:53:51 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
Nitro_Junkie, Собсно проблема всех СУБД - сильная оптимистичность. Они считают что если они не знают как коррелированы предикаты, будем считать что они никак не коррелированы, перемножают вероятности и уменьшают статистику (для сравнения пессимистичный сценарий вместо a1*a2 брать MAX(a1,a2). При этом если не угадал в меньшую сторону получишь NESTED LOOP JOIN (n*m) вместо HASH (n*logm), или JOIN двух таблиц по 10к записей (и хорошо если с Removed Filter на 990000 записей, а то может ее целиком в памяти материализовать) и т.п., а значит запрос повиснет (хорошо если сервер не упадет). Если же не угадал в большую то в n*m никогда не свалишься, в худшем случае будет n вместо m (но опять таки в жизни предикаты гораздо чаще коррелированы чем нет). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2014, 10:03:41 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
Вообщем реально изменил ситуацию пока только pg_trgm и существенно, так как запросы неизменны думаю существенно лучше никак. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2014, 11:57:10 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
its_me, план нужно смотреть, без него гадать только можно. сильно быстрее врядли получится, какие-то индексы возможно стоит поправить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2014, 13:25:38 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#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. Код: 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. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2014, 14:24:16 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
для "гу"(хотелось бы чтобы такое же время было): Код: 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. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2014, 14:47:26 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
its_me, ради интереса можно создать gin индекс вместо gist можно попробовать выполнить запрос с set enable_nestloop = off ну и индекс в template по template_id надо добавить (раньше был же). что показывает Код: sql 1. ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2014, 15:40:52 |
|
||
|
Как сократить время выполнения скрипта?
|
|||
|---|---|---|---|
|
#18+
Alexiusits_me, ради интереса можно создать gin индекс вместо gist можно попробовать выполнить запрос с set enable_nestloop = off ну и индекс в template по template_id надо добавить (раньше был же). что показывает Код: sql 1. ? 1. Пробовал, gin - в 10 раз дольше. 2. set enable_nestloop = off - с настройками не хочется экспериментировать, посмотрю... 3. индекс никуда не делся 4. показывает просто другое время(в 10 раз дольше чем надо) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2014, 15:47:21 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=38790326&tid=1998386]: |
0ms |
get settings: |
11ms |
get forum list: |
23ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
80ms |
get topic data: |
17ms |
get forum data: |
5ms |
get page messages: |
89ms |
get tp. blocked users: |
3ms |
| others: | 260ms |
| total: | 494ms |

| 0 / 0 |
