@BushaevDenis

Как оптимизировать sql запрос товаров opencart?

Добрый день, есть магазин на 700000 товаров.
В связи с этим страницы категорий грузятся секунд по 25.
Посмотрев какие запросы медленнее всего, нашёл 2:
getTotalProducts (Около 9 секунд)
getProducts (10-12 секунд)

Сам долгий запрос:
SELECT
   p.product_id,
   (
      SELECT
         AVG(rating) AS total 
      FROM
         oc_review r1 
      WHERE
         r1.product_id = p.product_id 
         AND r1.status = '1' 
      GROUP BY
         r1.product_id
   )
   AS rating,
   (
      SELECT
         price 
      FROM
         oc_product_discount pd2 
      WHERE
         pd2.product_id = p.product_id 
         AND pd2.customer_group_id = '1' 
         AND pd2.quantity = '1' 
         AND 
         (
(pd2.date_start = '0000-00-00' 
            OR pd2.date_start < NOW()) 
            AND 
            (
               pd2.date_end = '0000-00-00' 
               OR pd2.date_end > NOW()
            )
         )
      ORDER BY
         pd2.priority ASC,
         pd2.price ASC LIMIT 1
   )
   AS discount,
   (
      SELECT
         price 
      FROM
         oc_product_special ps 
      WHERE
         ps.product_id = p.product_id 
         AND ps.customer_group_id = '1' 
         AND 
         (
(ps.date_start = '0000-00-00' 
            OR ps.date_start < NOW()) 
            AND 
            (
               ps.date_end = '0000-00-00' 
               OR ps.date_end > NOW()
            )
         )
      ORDER BY
         ps.priority ASC,
         ps.price ASC LIMIT 1
   )
   AS special 
FROM
   oc_category_path cp 
   LEFT JOIN
      oc_product_to_category p2c 
      ON (cp.category_id = p2c.category_id) 
   LEFT JOIN
      oc_product p 
      ON (p2c.product_id = p.product_id) 
   LEFT JOIN
      oc_product_description pd 
      ON (p.product_id = pd.product_id) 
   LEFT JOIN
      oc_product_to_store p2s 
      ON (p.product_id = p2s.product_id) 
WHERE
   pd.language_id = '1' 
   AND p.status = '1' 
   AND p.date_available <= NOW() 
   AND p2s.store_id = '0' 
   AND cp.path_id = '5661' 
GROUP BY
   p.product_id 
ORDER BY
   p.sort_order ASC,
   LCASE(pd.name) ASC LIMIT 0,
   16


Сервер: 2ядра, 2gb ram.
Вопрос такой: Я знаю, что такое количесто товаро не мало, но всё же, 20 секунд это явно не нормально. Как можно оптимизировать запрос? Из-за какого подзапроса может быть такая шняга?
  • Вопрос задан
  • 688 просмотров
Пригласить эксперта
Ответы на вопрос 1
@rPman
Это что за треш запрос вы привели в вопросе?
В нем вложенные подзапросы в select это не просто бад практикс, это пиздец. Это так в opencart сделано или вы добавили? избавляйтесь от этого, понятно почему оно 20 секунд копается.

Как минимум запрос по oc_review выносится легко. С запросами по oc_product_discount и oc_product_special наверное нужно что то делать, там limit стоит, Даже не разбираясь в структуре проекта и прочего, я бы эти данные выносил тригером в соседнюю таблицу (т.е. эти 'тормоза' были бы в момент заливки данных о товарах и скидках в базу), а на запросе брал бы информацию из нее.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы