|
Нужно помощь в оптимизации простого LEFT JOIN запроса c WHERE из правой таблицы
|
|||
---|---|---|---|
#18+
Получаем продукты, в отдельной таблице лежат склады с количеством товара, через stock_id связываемся с текущим активным складом. Запрос: Код: plsql 1. 2. 3. 4. 5.
EXPLAIN: Код: html 1. 2. 3. 4. 5. 6. 7. 8. 9.
Таблица product: Код: 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. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182.
Таблица product_stock_value: Код: 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. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126.
Товаров 800к, запрос выполняется около 10 секунд. Что можно сделать для оптимизации? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2018, 19:47 |
|
Нужно помощь в оптимизации простого LEFT JOIN запроса c WHERE из правой таблицы
|
|||
---|---|---|---|
#18+
И возможно ли вообще? ) Можно конечно дублировать количество в основной таблице, но хотелось бы красиво. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2018, 19:49 |
|
Нужно помощь в оптимизации простого LEFT JOIN запроса c WHERE из правой таблицы
|
|||
---|---|---|---|
#18+
Не могу понять почему тут: -> Seq Scan on product p (cost=0.00..210915.78 rows=882784 width=1588) И тут: -> Seq Scan on product_stock_value s (cost=0.00..12496.93 rows=390714 width=4) идёт перебор всех записей. Ведь для stock_id и quantity созданы индексы. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2018, 19:54 |
|
Нужно помощь в оптимизации простого LEFT JOIN запроса c WHERE из правой таблицы
|
|||
---|---|---|---|
#18+
PavelTut, Код: plsql 1. 2.
Вероятно тут ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2018, 21:49 |
|
Нужно помощь в оптимизации простого LEFT JOIN запроса c WHERE из правой таблицы
|
|||
---|---|---|---|
#18+
PavelTutНе могу понять почему тут: -> Seq Scan on product p (cost=0.00..210915.78 rows=882784 width=1588) И тут: -> Seq Scan on product_stock_value s (cost=0.00..12496.93 rows=390714 width=4) идёт перебор всех записей. Ведь для stock_id и quantity созданы индексы. так вы пляшете от рейтингов . какое у вас распределение остатков ? если 0 в остатках много -- оптимально -- присунуть признак нулевого остатка в табличку товаров -- "денормализация" -- для условных индексов (никто не собирается решать задачу кросс-табных индексов на уровне движков) или кооптировать рейтинг в остатки -- с той же целью. и подумать над условными индексами. после оного телодвижа. если даже не денормализуя запихать с 2-х сторон составные инды "(рейт, ид)" и "(ид,остаток) где остаток >0", то возможно удастся пошить сносную иос--иос свертку с последующим чтением результатов для 10 отфильтрованных узлов.надо прикинуть по плотности 0. и вообще -- подумать, ага. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2018, 22:14 |
|
Нужно помощь в оптимизации простого LEFT JOIN запроса c WHERE из правой таблицы
|
|||
---|---|---|---|
#18+
sereginseregin, не, не тут. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2018, 22:30 |
|
Нужно помощь в оптимизации простого LEFT JOIN запроса c WHERE из правой таблицы
|
|||
---|---|---|---|
#18+
sereginseregin, о блин, спасибо, не заметил видео сразу. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2018, 22:38 |
|
Нужно помощь в оптимизации простого LEFT JOIN запроса c WHERE из правой таблицы
|
|||
---|---|---|---|
#18+
PavelTut, Код: sql 1. 2. 3. 4. 5. 6.
Этот запрос сколько выполняется? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2018, 23:01 |
|
Нужно помощь в оптимизации простого LEFT JOIN запроса c WHERE из правой таблицы
|
|||
---|---|---|---|
#18+
qwwq, Нулей примерно 5 часть. Денормализацию не представляю как тут. У одного товара может быть несколько остатков, на разных складах. Тут уже дублировать постоянно придётся, но не важно. Спасибо, тормознул чего-то насчёт составных индексов. С индексом 'rating', 'stock_id' в основной и 'id', 'quantity' в присоединенной таблице всё работает моментально. Если ORDER BY p.rating DESC Если же к ордеру добавить NULLS LAST то уже составные индексы не применяются, нужно разобраться. Но тут в приложении сменю NULL на 0. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2018, 23:07 |
|
Нужно помощь в оптимизации простого LEFT JOIN запроса c WHERE из правой таблицы
|
|||
---|---|---|---|
#18+
ursido, Спасибо! Немного поспешил. С сортировкой по рейтингу этот запрос остался таким же, хоть и срабатывают составные индексы (прошлый раз кеш бд сработал, а я уже обрадовался :) ) Код: plsql 1. 2. 3. 4. 5.
А этот моментально! Применяется только один составной индекс rating__stock_id Код: plsql 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2018, 23:43 |
|
Нужно помощь в оптимизации простого LEFT JOIN запроса c WHERE из правой таблицы
|
|||
---|---|---|---|
#18+
PavelTutПолучаем продукты, в отдельной таблице лежат склады с количеством товара, через stock_id связываемся с текущим активным складом. Запрос: Код: plsql 1. 2. 3. 4. 5.
Товаров 800к, запрос выполняется около 10 секунд. Что можно сделать для оптимизации? Попробуйте 1)Добавить индекс на on product(rating DESC NULLS LAST) и переписать запрос как SELECT p.* FROM product p WHERE EXISTS (SELECT * FROM product_stock_value s WHERE p.stock_id = s.id AND s.quantity > 0) ORDER BY p.rating DESC NULLS LAST LIMIT 10 скорее всего получите index scan по новому индексу и nested loop по product_stock_value для фильтрации для дополнительного ускорения я бы еще сделал уникальный (наверное если это id) индекс ON product_stock_value(id) WHERE quantity > 0 тогда еще быстрее будет. Ну и перед тем как делать explain analyze обязательно стоит сделать vacuum analyze На обе эти таблицы (это вообще полезно делать после добавления индексов на всякий случай для получения внятной статистики). -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
17.02.2018, 06:43 |
|
Нужно помощь в оптимизации простого LEFT JOIN запроса c WHERE из правой таблицы
|
|||
---|---|---|---|
#18+
Maxim Boguk, Спасибо. Глянул Ваше видео сверху, понял только первую часть про оффсеты и двойную сортировку (почти), дальше мрак :), не хватает знаний. Я же поставил для рейтинга по-умолчанию значение 0 и отказался от NULLS LAST. Установил для теста минимальное значение shared_buffers = 128kB (для тестирования это правильно?) Ваш пример с вложенным селектом и с джойном работают примерно одинаково: Код: plsql 1. 2. 3. 4. 5.
С джойном: Код: plsql 1. 2. 3. 4. 5.
EXPLAIN ANALYZE Код: html 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
Во вложенной создал индекс id__quantity, в основной rating__site_code__status и всё замечательно! ... |
|||
:
Нравится:
Не нравится:
|
|||
17.02.2018, 19:51 |
|
|
start [/forum/topic.php?fid=53&tid=1995938]: |
0ms |
get settings: |
12ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
41ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
53ms |
get tp. blocked users: |
2ms |
others: | 22ms |
total: | 165ms |
0 / 0 |