|
|
|
(MySQL) Оптимизация запроса (16 сек)
|
|||
|---|---|---|---|
|
#18+
Всем доброго времени суток. Нужна помощь в оптимизации запроса (MySQL). Это запрос на кол-во аттрибутов у отфильтрованных товаров. В нем есть 3 подзапроса из таблиц (product_special, product_discount, product_to_category). Сам запрос выполняется ~17 сек. Если первые два подзапроса убрать, то работает относительно быстро (0.7 сек). С механизмом работы mysql знаком плохо, поэтому не знаю как правильно решить задачу(и вообще не знаю). EXPLAIN показал, что тормоза из-за создания временных таблиц (Use temporary). Пробовал реализовать Full Outer Join к таблицам product_special и product_discount посредством двух запросов и UNION ALL, но возвращает 0 строк, до конца так и не разобрался. Код: 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. Ссылка на дамп БД с таблицами (unpacked 18Mb). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.05.2015, 14:51:21 |
|
||
|
(MySQL) Оптимизация запроса (16 сек)
|
|||
|---|---|---|---|
|
#18+
halfhope, Приведите планы всех подзапросов отдельно, особенно первого и общий план - тоже не помешает. Варианты из ХШ: 1. Первый подзапрос идет "без индексов"; 2. Первый подзапрос материализуется (большая выборка = запись на диск) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.05.2015, 15:40:41 |
|
||
|
(MySQL) Оптимизация запроса (16 сек)
|
|||
|---|---|---|---|
|
#18+
Еще раз повторю запрос, отформатировал с комментариями Код: 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. EXPLAIN первого: Кстати, чем меньше элементов в этой таблице (product_special) тем меньше скорость выполнения общего запроса. По отдельности они все быстрые. Второго: Третьего: Общий: Результаты профилирования общего запроса: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.05.2015, 20:58:43 |
|
||
|
(MySQL) Оптимизация запроса (16 сек)
|
|||
|---|---|---|---|
|
#18+
А что Вы хотите? Вы справа приматываете к таблице пухлые неиндексированные подзапросы - ясен пень оно не помещается в памяти и оттого льётся на диск. Вот Вам реально нужно именно ЛЕВОЕ связывание? и именно в НАЧАЛЕ цепи считывания таблиц? Я вижу, что данные этих подзапросов используются исключительно в секции WHERE. А часть выгребаемых полей вообще нахрен не нужна... В общем, перепишите свой запрос, руководствуясь строгой логикой и здравым смыслом - и он если и не взлетит, то уж подпрыгнет стопудово. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.05.2015, 21:57:43 |
|
||
|
(MySQL) Оптимизация запроса (16 сек)
|
|||
|---|---|---|---|
|
#18+
halfhope, ХШ оказался прав на все 100%. Что можно сделать? 1. Внести в секции ON левых джойнов из секции WHERE все "их" условия. То бишь какую табличку лепите, от той coalesce и пришейте. Константы можно и повторить, на скорость движения они не влияют.. 2. Перенести внутренний join в начало сборки. Все "левые" джойны должны пришиваться "апосля". Собственно в секции WHERE у вас должно остаться ровно то, что относится к основной табличке и внутренним объединениям (этим - пофиг)... пробуйте. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2015, 15:07:38 |
|
||
|
|

start [/forum/topic.php?desktop=1&fid=47&tid=1833182]: |
0ms |
get settings: |
5ms |
get forum list: |
8ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
89ms |
get topic data: |
5ms |
get forum data: |
1ms |
get page messages: |
23ms |
get tp. blocked users: |
1ms |
| others: | 199ms |
| total: | 335ms |

| 0 / 0 |
