Как ускорить Opencart при большом кол-ве товаров?

Имеется интернет-магазин канцелярии, 17500 позиций номенклатуры. Магазин очень долго работает. Все тормозит.
Улучшение сервера результата не дало.
Отключение подсчета кол-ва товаров, добавление индексов - не принесло ощутимой пользы.
Все страницы очень долго грузятся.
Тормозит все MySQL, поскольку в Opencart очень большие запросы, с множествой вложений и ORDER BY.
Сейчас база MyIsam, где-то читал, что на InnoDB не советуют переводить OpenCart.
В последнее время очень часто стали приходить отчеты по Яндекс.Метрике, что сайт недоступен.
Кеширование Memcache включено - не помогает.
Как можно его оптимизировать?
Или на какой другой движок можно перейти? чтобы быстро и с минимальными затратами.
Часто выполняемый медленный запрос MySQL
Count: 46  Time=6.91s (317s)  Lock=0.05s (2s)  Rows=1.0 (46), 
  SELECT DISTINCT *, pd.name AS name, p.image, m.name AS manufacturer, 
  (SELECT price 
      FROM oc_product_discount pd2 
      WHERE pd2.product_id = p.product_id AND pd2.customer_group_id = 'S' 
            AND pd2.quantity = 'S' AND ((pd2.date_start = 'S' OR pd2.date_start < 'S') 
            AND (pd2.date_end = 'S' OR pd2.date_end > 'S')) 
       ORDER BY pd2.priority ASC, pd2.price ASC LIMIT N) AS discount, 
    (SELECT price 
       FROM oc_product_special ps 
       WHERE ps.product_id = p.product_id AND ps.customer_group_id = 'S' 
                  AND ((ps.date_start = 'S' OR ps.date_start < 'S') AND (ps.date_end = 'S' OR ps.date_end > 'S')) 
        ORDER BY ps.priority ASC, ps.price ASC LIMIT N) AS special, 
     (SELECT points 
        FROM oc_product_reward pr 
        WHERE pr.product_id = p.product_id AND customer_group_id = 'S') AS reward, 
     (SELECT ss.name 
         FROM oc_stock_status ss 
         WHERE ss.stock_status_id = p.stock_status_id AND ss.language_id = 'S') AS stock_status, 
      (SELECT wcd.unit 
          FROM oc_weight_class_description wcd 
          WHERE p.weight_class_id = wcd.weight_class_id AND wcd.language_id = 'S') AS weight_class, 
       (SELECT lcd.unit 
           FROM oc_length_class_description lcd 
           WHERE p.length_class_id = lcd.length_class_id AND lcd.language_id = 'S') AS length_class, 
        (SELECT AVG(rating) AS total 
            FROM oc_review r1 
            WHERE r1.product_id = p.product_id AND r1.status = 'S' 
            GROUP BY r1.product_id) AS rating, 
         (SELECT COUNT(*) AS total 
             FROM oc_review r2 
             WHERE r2.product_id = p.product_id AND r2.status = 'S' 
             GROUP BY r2.product_id) AS reviews, 
        p.sort_order FROM oc_product p 
    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) 
    LEFT JOIN oc_manufacturer m ON (p.manufacturer_id = m.manufacturer_id) 
    WHERE p.product_id = 'S' AND p.status = 'S' AND p.date_available <= 'S' AND p2s.store_id = 'S'
  • Вопрос задан
  • 14123 просмотра
Пригласить эксперта
Ответы на вопрос 7
vodnicear
@vodnicear
Лучший вариант самописный движок.
Ответ написан
Комментировать
zoonman
@zoonman
⋆⋆⋆⋆⋆
17500 - это ничтожно малое количество записей.
У Опенкарта основная проблема - говнокод на уровне обращений к базе данных. Много запросов в цикле и т.д.
Решается обычно установкой MySQL на нормальную машину с хорошим объемом памяти и SSD, миграцией на InnoDB, анализом запросов и построением необходимых индексов. Кроме индексов необходимо отследить размеры буферов и т.д. В вашем случае объем памяти должен быть в районе от 8 GB RAM. Из решений рекомендую использовать не MySQL, а MariaDB или PerconaDB. Не используйте виртуальный (shared) хостинг.
Еще поищите, есть хорошая утилита mysqltuner, она подсказывает оптимальные характеристики для СУБД.
Включите лог медленных запросов и запросов неиспользующих индексы.
Проанализируйте сетевой стек вашего соединения с MySQL, работа через сокет значительно ускоряет работу приложения. Некоторые горе-мастера выставляют адрес домена, который система переодически ресолвит и это увеличивает издержки на время соединения.
При высокой посещаемости и некритичности актуальности данных используется подход с переписыванием слоя абстракции БД опенкарта с применением кеширования результатов в Memcached. Актуально для высокопосещаемых ресурсов с разного рода предзаказами или проверкой остатков непосредственно при добавлении заказа.
Ответ написан
@egormmm
Борітеся — поборете!
Если тормозит Mysql - то нужно включить лог медленных запросов, найти где они создаются в движке и оптимизировать их.
Раздел "оптимизация" в руководстве по Mysql также сможет помочь.
Если все индексы правильно расставлены, то скорее всего в запросах используется функция, которая не позволяет Mysql кешировать запрос. Этим грешат разные модули, например Mega filter.

P.S. Надеюсь, что кеш запросов Mysql включен.
Ответ написан
thewind
@thewind
php программист, front / backend developer
Тормозит все MySQL, поскольку в Opencart очень большие запросы, с множествой вложений и ORDER BY.

Почему бы не сесть и планомерно не исправить все нужные запросы? Разделяя их на несколько, оптимизируя и прочее-прочее.
Ответ написан
Комментировать
@amfetamine
исправьте некоторые медленные запросы к БД, повесьте кэш где нужно, еще можете на vds перепрыгнуть или может быть будет достаточно просто хорошего хостинга. был тут недавно один сайт, пока на vds не перекинули его, летать не начал, тоже было достаточное количество товаров и описания к ним
Ответ написан
@devopencart2
Программист, пишу сайты и модули на Opencart
как правило, отключение подсчета товаров не влияет на скорость (хоть об этом все и пишут, я не исключение))

но есть ещё множество манипуляций, которые могут помочь ускорить сайт.

Можете попробовать реализовать несколько или все пункты из этого мануала:
https://in-it24.com/uskorenie-magazina-na-opencart/
Ответ написан
Комментировать
@fbi_agent26
memcached для опенкарта это вещь бесполезная, я включал, скорость загрузки пхп не то чтобы существенно снизилась, она выросла, с 0.17 сек в среднем , до 0.35 сек в среднем, я 10 раз замерял каждый вариант и высчитывал среднее значение.
Индексы нужно не везде делать, а только там где они нужны, у вас при открытии товара идет запрос по айди в несколько таблиц, вот в самые жирные и делайте.
========== если opencart медленно грузится и товаров меньше 100 000 ================
1 - виртуальный хостинг имеет общий сервер баз данных, на который выделяется одно ядро сервера, потому ускорить ее вы не сможете оптимизациями, ниже статистика моей бд.
ø за час: 860 877
ø за минуту: 14 347
ø в секунду: 239
Хостинг позволяет ставить ее на виртуальный аккаунт, но если я туда ставлю ее, то все мелкие сайты начинают лагать, нагрузку на бд никто там не высчитывает.
Кто хочет оптимизировать бд то идите сразу на сервер, или купите модуль кеширования, кеш запросы идут в обход бд, из оперативной памяти, и сразу идет готовый результат, есть такие модули.
================Лишние модули===============
Есть у меня модуль lighting , он показывает запросы, и как то время выполнения запросов к бд выросло с 0.05 секунд до 0.10-0.15, пошел искать, нашел что seo модуль, который я использовал для генерации мета тегов, занимает большую часть этого времени, выключил естественно, если вы не используете модули а они есть - их надо выключать.
===============================================================
Товаров у меня 500 000, время загрузки страницы 0.2 когда нет особого трафика и боты не нападают.
С модулем кеширования ( не буду называть какой , их много , выбирайте любой ) , скорость генерации страницы 0.01, при этом сайт у меня не интернет магазин, он постоянно обновляется ботами на node.js , который и создают нагрузку на бд, у вас скорость будет выше, если все правильно сделать.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы