|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#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.
EXPLAIN ANALYZE выдает такое: Код: 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.
Пробовал создавать такие индексы: Код: plaintext 1. 2. 3. 4. 5. 6.
Размерность таблиц: files 3,2 mln tths 1,6 mln folders 0,2 mln services 235 servers 222 VACUUM ANALYZE делал. Какие еще меры, помимо обновления железа (планируется в будущем) можно предпринять? Структура таблиц приведена ниже: Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
15.06.2008, 15:32 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
Возможно поможет кластерный индекс. http://www.postgresql.org/docs/8.2/static/sql-cluster.html Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
15.06.2008, 20:48 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
Код: plaintext 1. 2. 3.
Код: plaintext 1.
Код: plaintext 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
16.06.2008, 11:00 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
2Гостик: Пытался делать кластерный индекс (ох, как это долго все происходило :) по files(name), но не помогло. Этот индекс не использовался. 2LeXa_NalBat: А если я пишу Код: plaintext
Прикрутил полнотекстовый поиск, создал для него GIN индекс. Круто. Быстро. Ничего не скажешь :) Код: 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.
Это можно сделать при помощи полнотекстового поиска? В мануале чего-то такого не нашел... ... |
|||
:
Нравится:
Не нравится:
|
|||
16.06.2008, 12:43 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
UKYА если я пишу Код: plaintext
UKYВо всяком случае создал такой индекс, но СУБД не хочет его использовать (EXPLAIN ANALYZE см. ниже). Код: plaintext 1. 2. 3. 4.
UKY Код: plaintext 1. 2. 3.
UKYВот только хотелось бы найти именно то слово, которое было задано в запросе. Т.е. если спросили "панда", то должно вернуться "Панда", "Пандамима", "Недопандас" и все в этом роде, но не "панды", "пандой"... Это можно сделать при помощи полнотекстового поиска? В мануале чего-то такого не нашел...я с полнотекстовым поиском не работал. может быть можно в качестве разделителя "слов" считать "границу букв"? тогда каждую букву полнотекстовый поиск будет считать отдельным словом, и получите нужны вам поиск. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.06.2008, 13:53 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
"постгрес не умеет оценивать объем выборки по полнотекстовому индексу" может обернуть полнотекстовый поиск по files.name в функцию на языке sql, для которой при создании указать ROWS например равным 10, также можно указать COST. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.06.2008, 15:03 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
Попробовал Код: plaintext
LeXa NalBatя с полнотекстовым поиском не работал. может быть можно в качестве разделителя "слов" считать "границу букв"? тогда каждую букву полнотекстовый поиск будет считать отдельным словом, и получите нужны вам поиск. Это сделать реально, но там тогда придется не каждую букву, а все части слова выделять, а это ох сколько памяти и времени на постоение индексов занимать будет... Пока думаю сделать полнотекстовый поиск и уже результаты выборки доколнительно проверять LIKE '%панда%'. Хотя тоже часть результатов теряться будет... LeXa NalBat"постгрес не умеет оценивать объем выборки по полнотекстовому индексу" может обернуть полнотекстовый поиск по files.name в функцию на языке sql, для которой при создании указать ROWS например равным 10, также можно указать COST. Тут я уже Вас не понимаю :) Еще ни разу не писал функции на постгресе. Может быть поэтому... Огромное Вам спасибо за помощь! ... |
|||
:
Нравится:
Не нравится:
|
|||
18.06.2008, 19:55 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
UKY Вот только хотелось бы найти именно то слово, которое было задано в запросе. Т.е. если спросили "панда", то должно вернуться "Панда", "Пандамима", "Недопандас" и все в этом роде, но не "панды", "пандой"... Это можно сделать при помощи полнотекстового поиска? В мануале чего-то такого не нашел... в 8.3 и младше нельзя, в 8.4 будет можно (уже в CVS даже есть) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.06.2008, 02:21 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
UKY LeXa NalBatможет обернуть полнотекстовый поиск по files.name в функцию на языке sql, для которой при создании указать ROWS например равным 10, также можно указать COST.Тут я уже Вас не понимаю :) Еще ни разу не писал функции на постгресе. Может быть поэтому...думаю, что это ухищрение может ускорить запрос. сделать что-то типа Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
... |
|||
:
Нравится:
Не нравится:
|
|||
19.06.2008, 12:31 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
iz UKY Вот только хотелось бы найти именно то слово, которое было задано в запросе. Т.е. если спросили "панда", то должно вернуться "Панда", "Пандамима", "Недопандас" и все в этом роде, но не "панды", "пандой"... Это можно сделать при помощи полнотекстового поиска? В мануале чего-то такого не нашел... в 8.3 и младше нельзя, в 8.4 будет можно (уже в CVS даже есть) Круто :) Надо будет как-нибудь попробовать этот патчик прикрутить... 2 LeXa NalBat: Это ухищрение не сработало :) Постгрес не обманишь... ... |
|||
:
Нравится:
Не нравится:
|
|||
19.06.2008, 20:40 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
До выхода версии 8.4 можно сделать поиск по триграммам - контриб pg_trgm. Он шустро работает, правда UTF-8 не понимает. Принцип такой: 1) Сделать таблицу для хранения отдельных слов Код: plaintext 1.
2) Исходный текст разбить по словам. Можно с помощью ts_vector+ts_stat как в мануале, можно регуляркой Код: plaintext 1. 2. 3.
3) Установить в сессии низкий порог поиска функцией set_limit(), в районе 0.1-0.2. Чем меньше порог, тем больше будет ложных совпадений и медленнее поиск, но зато и нужных слов попадет больше. 4) Поиск должен идти сначала оператором % , а потом из уже ограниченного набора строк надо отсечь мусор обычным like Код: plaintext 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2008, 05:38 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
UKY2 LeXa NalBat: Это ухищрение не сработало :) Постгрес не обманишь...покажите explain analyze ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2008, 10:33 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
Оказывается, запрос по словам и не тормозит вовсе :) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Все тормоза уходят в join. На построение всяких хэш таблиц и всего такого: Код: 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.
Код: 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.
Еще раз пробовал "set enable_hashjoin to off". Запрос выполнялся 250 секунд и использовался "Merge Join". P.S.: В понедельник уезжаю на военные сборы. Так что полтора месяца не буду вас всех доставать :) P.P.S.: Огромное всем спасибо за предложенные варианты ускорения запроса. Сам бы до такого никогда бы не додумался :) ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2008, 14:27 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
UKYВсе тормоза уходят в join. На построение всяких хэш таблиц и всего такогода. но для этого запроса возможен быстрый план. тормоза происходят из-за того, что постгрес выбирает неоптимальный порядок (или тип) джоинов. причина этой ошибки в том, что он неправильно оценивает кол-во строк удовлетворяющих условию полнотекстового поиска. попробуйте обернуть полнотекстовый поиск в функцию, созданную с опцией ROWS 10, как я писал, это может помочь. покажите explain analyze с использованием функции-обертки. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.06.2008, 11:04 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
Вернулся со сборов. Жив и здоров :) LeXa NalBat UKYВсе тормоза уходят в join. На построение всяких хэш таблиц и всего такогода. но для этого запроса возможен быстрый план. тормоза происходят из-за того, что постгрес выбирает неоптимальный порядок (или тип) джоинов. причина этой ошибки в том, что он неправильно оценивает кол-во строк удовлетворяющих условию полнотекстового поиска. попробуйте обернуть полнотекстовый поиск в функцию, созданную с опцией ROWS 10, как я писал, это может помочь. покажите explain analyze с использованием функции-обертки. Сделал так, как Вы мне порекомендовали: Код: 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.
Получил это: Код: 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.
Индексы, которые есть в СУБД: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
Ну что-то ни в какую не хочет оптимизироваться запрос... ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2008, 16:16 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
- если поиск по %панда% возвращает немного записей, то можно сохранить их во временную таблицу, а уж потом джойнить с остальным хохяйством. - выделить часть запроса во view, часто это позволяет загнать запрос в более оптимальный план. Например подзапрос (select distinct on ...) ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2008, 18:45 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
tadmin- если поиск по %панда% возвращает немного записей, то можно сохранить их во временную таблицу, а уж потом джойнить с остальным хохяйством. - выделить часть запроса во view, часто это позволяет загнать запрос в более оптимальный план. Например подзапрос (select distinct on ...) Сделал временную таблицу - не помогло. И вид тоже делал - та же ситуация. P.S.: В основном нагрузка идет на процессор. Жесткий диск не так уж и пыжится. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2008, 06:26 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
а если Код: plaintext 1. 2. 3. 4.
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Кстати, я не понял из схемы данных, нельзя ли кое-где указать inner join ? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2008, 13:07 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
tadminа если Код: plaintext 1. 2. 3. 4.
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Кстати, я не понял из схемы данных, нельзя ли кое-где указать inner join ? PostgreSQL The words INNER and OUTER are optional in all forms. INNER is the default; LEFT, RIGHT, and FULL imply an outer join. Так что здесь и так используется inner join ;) Сделал так, как Вы мне посоветовали за исключением того, что убрал "where type is null and tth is null" из вида, т.к. логика страдает: type - тип файла. Для директории = null tth - контрольная сумма файла. Для директории = null А мне надо найти и файлы, и папки. Запрос Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
Главная задача - оптимизация Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2008, 13:34 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
вот этот Код: plaintext
У меня был похожий случай, победил через view. У вас большой pg_dump, можете выложить? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2008, 15:17 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
tadminвот этот Код: plaintext
У меня был похожий случай, победил через view. У вас большой pg_dump, можете выложить? До меня только сейчас дошло как узнать с какого места в запросе тормоза начинаются %) pg_dump большеват. да и скорость интернета не очень большая. сделал set enable_seqscan to off и запрос выполнился за 2,5 секунды: Код: 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.
Это уже хорошо. Даже очень :) Но можно ли как-нибудь без принудительной установки параметров оптимизатора этого добиться? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2008, 21:32 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
UKY До меня только сейчас дошло как узнать с какого места в запросе тормоза начинаются %) pg_dump большеват. да и скорость интернета не очень большая. Тормоза (по времени) у вас начинались с hash-join's в памяти, но вот вызвала их никчемная туча записей. Это относительно простой случай, потому что в итоге мало записей возвращается, а sec-scan - большой. Могло быть и так, что делается несколько выборок, которые медленно сужают число записей, делают им hash-join, в то время как в самом конце выполняется условие where, которое и так бы все это отрезало. Стоит заставить планировщик применить первым самое жестокое правило, как все начинает летать. UKY сделал set enable_seqscan to off и запрос выполнился за 2,5 секунды: Но можно ли как-нибудь без принудительной установки параметров оптимизатора этого добиться? При объединении 8-10 таблиц(подзапросов) с кучей условий объединения безумно растет количество возможных планов исполнения. Для 8-10 таблиц оно может измеряться в тысячах. Планировщик видит это и не выбирает аналитически оптимальный, а лишь делает "догадку". (Читать про GQO). Я замечал (не надо мне верить, это догадки), что при большом числе таблиц даже порядок их перечисления в запросе может радикально повлиять на план исполнения, а небольшое изменение в статистике таблиц может внезапно "опрокинуть" до сих пор работавший план запроса. В подобной ситуации я добился оптимального плана через комбинацию нескольких view. Попробуйте разбить ваш запрос на относительно простые части и реализуйте их в виде view так, чтобы финальный запрос можно было построить на их комбинации. Если каждая view будет исполнятся с оптимальным планом, есть шанс на то же самое в целом. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.07.2008, 09:52 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#18+
Попробуйте на набор запросов разбить и отлаживайте их по шагам. Если промежуточный запрос дает мало записей - сохраняйте во временную таблицу, много записей - делайте вид. См. http://postgrestips.blogspot.com/2007/07/temp.html ... |
|||
:
Нравится:
Не нравится:
|
|||
27.07.2008, 11:28 |
|
Оптимизация большого запроса возможна?
|
|||
---|---|---|---|
#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.
Только вот одна маленькая проблема: в вИды нельзя передавать параметры. А мне надо как-то передать строку "панда". Как лечить? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.07.2008, 11:43 |
|
|
start [/forum/topic.php?fid=53&msg=35384360&tid=1995161]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
44ms |
get topic data: |
8ms |
get forum data: |
3ms |
get page messages: |
62ms |
get tp. blocked users: |
1ms |
others: | 16ms |
total: | 165ms |
0 / 0 |