|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
Есть запрос, который извлекает из 'Attachaments' данные одной строки, у которой наибольший id, у которой есть строки в Transactions и в Tickets: Код: plsql 1. 2. 3. 4.
выполняется долго и ресурсов жрет. Выполняется часто. Explain analyze: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
В 'Аttachments' - 31 млн, в 'Transactions' - 66 млн, в 'Tickets' - 8 млн строк. Индексы по 'Attachments': Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Индексы по 'Transactions': Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9.
Предложил заменить его на другой, в котором, использую наибольшие 10 000 id: Код: plsql 1. 2. 3. 4. 5. 6. 7.
выполняется за 240 ms. Но! Требуют подменять в базе. тогда я создал 2 вьюхи att_join_tran, att_join_tran_new на основе старого и нового запросов и хотел создать правило: Код: plsql 1. 2. 3.
В документации говорится: https://www.postgresql.org/docs/9.1/sql-createrule.html table The name (optionally schema-qualified) of the table OR VIEW (!) the rule applies to. Непонятно как подменить запрос один - другим? (В Oracle - это решается materialized view.) Версия 9.1 ... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 13:15 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
maxski, вместо join и distinct в данном запросе следует использовать конструкцию exists, особенно если есть уверенность что нужные строки всегда найдутся сразу в конце таблицы attachments. можно еще попробовать заменить distinct на distinct on(main.id), но не факт что это уберет hash join'ы. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 14:16 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
maxski, У вас запрос неверно написанный. Делать JOIN чтобы он создавал дубликаты а потом делать distinct чтобы их убрать - так делать не надо (и нормально оно никогда работать не будет). Правильно вот так вот Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
И дальше его оптимизировать. Впрочем чудес ожидать не стоит 9.1 версия древняя как мамонты и такая же не сильно умная с т.з. оптимизации. PS: То что база исходный ваш запрос нормально не выполняет - так и 12 версия его выполнять не будет. Не делайте так. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 14:22 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
Maxim Boguk, Alexius , спасибо, что откликнулись. Запрос не мой ("мопед не мой"), это Request Tracker 4. Он вроде как на лету генерит запросы. По этой причине, мне не дают его (запрос) переписать. Мне было предложено оптимизировать на стороне базы. Поэтому я зашел со строны create rule: Код: plsql 1. 2. 3.
Я так понял, что вьюха, на основе старого запроса att_join_tran не прошла потому, что в ней несколько таблиц присутствует (?). Обещали "железо" для перехода на новую версию сервера. Вот пока жду. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 14:53 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
maxskiMaxim Boguk, Alexius , спасибо, что откликнулись. Запрос не мой ("мопед не мой"), это Request Tracker 4. Он вроде как на лету генерит запросы. По этой причине, мне не дают его (запрос) переписать. Мне было предложено оптимизировать на стороне базы. Поэтому я зашел со строны create rule: Код: plsql 1. 2. 3.
Я так понял, что вьюха, на основе старого запроса att_join_tran не прошла потому, что в ней несколько таблиц присутствует (?). Обещали "железо" для перехода на новую версию сервера. Вот пока жду. Ни железо ни новая версия сервера ни rules при невозможности целиком переписать запрос - не помогут в данной конкретной ситуации. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 15:01 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
Maxim Boguk, вот explain analyze для вашего запроса с exist (full scan 'tickets' - 8млн и full scan 'transactions' - 66 млн строк). И время выполнения 2мин. Вместо 4 мин на старом запросе. Не сильно лучше. Прошу прощения за критику. Код: 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.
я бы воткнул бы max(id) для 'Attachments', если б 100% был бы уверен, что в такая строка найдется в Transactions и Tickets. Выполняется мгновенно (2ms). Но нет гарантии, что строка найдется. Код: 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.
Надо идти по пути уменьшения объёма извлечения. Поэтому, я в своем "костыле" (см парой постов выше) я ограничился 10тыс строк от верхнего конца. Это все же лучше, чем 31 млн ))) ... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 15:24 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
Maxim Boguk, у меня свободного места осталось 200ГБ из 3.5ТБ. и 1ГБ в день отщелкивается. Мне без нового "железа" никак не перейти на новую версию сервера. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 15:34 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
maxski, Интересно как... А если перед explain моей версии сделать set enable_hashjoin=off; set enable_mergejoin=off; то план нормальнее не становится? PS: для теста чтобы проверить что это не проблема в слишком старой версии базы попробуйте упрощенную (неполную) версию запроса еще explain analyze сделать вида Код: plsql 1. 2. 3. 4. 5.
и вида Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
-- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 16:28 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
Maxim Boguk, первый: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
второй: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
и ваш запрос с set ...= off Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 16:53 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
maxski, а если еще для полной версии запроса сделать enable_material=off ? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 17:01 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
maxski, Да чтобы exists с join внутри работал быстро нужен хотя бы 9.2. Увы тут вы уже на ограничения 9.1 попадаете. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 17:05 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
Maxim Bogukmaxski, а если еще для полной версии запроса сделать enable_material=off ? Код: 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.
Вот (внизу) attachments.id, которые имеют строки в Transactions и в Tickets. Видно, что в каждой десятке есть пара-тройка id. Среди десяток - я не встретил пропусков (на последней 1000). Ну и соответственно в каждой сотне есть хотя бы один id (со строками в Transactions и в Tickets). Не говоря уже про последние 10 тыс id. т.е. выбрав последние 10тыс attachments.id у нас будет практически 100% вероятность, что будет хотя бы один id cо строками в Transactions и в Tickets. Смотрим: Время выполнения запроса 52ms, на версии 9.1 Код: 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.
Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 18:02 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
maxski, а так? Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 18:41 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
Alexius, второй вариант выполнился мгновенно: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 20:37 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
Alexius, с exist'ом ужк приводил выше. Еще раз. Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 20:39 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
maxski, у меня немного другой exists был. используйте вариант с distinct on значит. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.02.2019, 21:12 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
Alexius, Спасибо за отличный вариант! ... |
|||
:
Нравится:
Не нравится:
|
|||
28.02.2019, 10:02 |
|
Оптимизировать запрос
|
|||
---|---|---|---|
#18+
Небольшое дополнение по поводу моего "костыля" с выборкой последних 10 тыс строк из attachments: Проанализировав данные в attachments, я пришел к тому же выводу, что и раньше, что в последних 10 тыс строк найдется хотя бы одно одна строка имеющая строку(строки) в Tickets и в Transactions: Ниже вывод запроса подсчитавшего пропуски в Attachments: Код: 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.
Может кому пригодится аналогично подсчитать пропуски в последовательностях. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.03.2019, 11:32 |
|
|
start [/forum/topic.php?fid=53&fpage=43&tid=1995313]: |
0ms |
get settings: |
11ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
39ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
2ms |
others: | 16ms |
total: | 163ms |
0 / 0 |