Тормозит Opencart часть 15 | Наследие упырей

bikegirl

Тормозит Opencart часть 15 | Наследие упырей

Сначала анекдот.

Приходит хирург кардиолог к автомастеру, двигатель мол кряхтит — посмотри.
А болторез давай ныть.
— Почему мол ты получаешь 5000 долларов за операцию, а я 500 за капитальный ремонт движка?
Хирург завел двигатель и говорит — «на ремонтируй, я тебе заплачу 5000″.

Век живи век учись.

Я недавно заглядывал в Престу, 2 000 товаров, тормозит как скотина. Вроде бы все инструменты есть для аудита в ней встроенные. А с налета сделать ничего не смог. Пришлось бы переписать полдвижка. С Опенкартом же, уже давно все понятно. Мой первый пост про тормоза Opencart появился почти два года назад в январе 2014 го, с того времени магазинов в лицо и изнутри я поведал наверное штук 600 уже, и 99% стали работать зашибись.

И вдруг попадается мне магазин на opencart 1.4.8. Я уже забыл что там да как, версии движка этой лет 6, там даже класса кеша нет. Но при этом жирный сервант, вроде как какие то умники проставили индексы и все равно тормозит. При этом, тупит главная а все остальные страницы открываются в рамках.

Умники которых было до меня 5 человек, заявили, что мол мы ничего не можем сделать, движок гавно, индексы в базе есть, сервант жирный. Меняйте движок.

Но послушайте господа, 1.4.8 — это утилитарное гавно. При правильно затюненной базе, там тормозить просто нечему. Там даже сеоурлы в таблице product. И нет лишнего хлама в виде схем, кучи статусов всего чего только можно, api, отслеживаний активности пользователей и кучи хлама который появился в 2.x.

Вот тут я подзавис. Так как доступа к сереверу у меня нет. VMOD нет. PhpMyAdmin на сервере нет. Профайлера под 1.4 у меня нет. А если бы и был. У владельца магазин — он же CRM и укладывать его даже на полчаса нельзя.
На помощь пришел мод фрилансера, который db_log под 1.5, хорошо что в 1.4 и 1.5 библиотека db.php не сильно отличается или не отличается совсем. Очень быстро лог медленных запросов перевалил за пару мегабайт и было над чем работать.

И у нас обнаружилась вот такая конструкция

SELECT * FROM oc_product ……. ORDER BY RAND() LIMIT 0,3

Вылезло это в модуле Вафловиса, который выводил из избранных категорий по три случайных товара на главную. Все упыри делают свои модули на 20 дефолтных товарах из свежеустановленной сборки и забывают, что товаров может быть не только лишь 2.

И так 10 раз по 500 миллисекунд на выполнение запроса. А трафла на магазине в пик человек 20-30 в минуту. Вот они зашли и выгрызли весь ресурс у mysql.

Плюс 5 секунд загрузка главной (которая якобы не оптимизируется и меняйте движок) — это овердохуя.

Лечиться все просто. Вместо выборки трех случайных записей из сложносочлененного массива данных несколькими джоинами, отсортированного случайным образом, делаем вот так. Ограничиваем выборку случайных значений только по полю product_id, на порядок уменьшая диапазон сортируемых значений, соответственно, на порядок увеличивая скорость обработки запроса.

SELECT product_id FROM oc_product ……. ORDER BY RAND() LIMIT 0,3

Потом перебираем получившийся массив, через model_catalog_product->getProduct($product_id) получаем полные данные по нашим трем товарам. И на выходе получаем 250мс полную генерацию страницы.

Четыре специалиста. Порядка 500 долларов в труху потраченных на их услуги-заслуги. И решение, которое лежит на поверхности.

По моему это уже старость. И мне пора устраиваться Juniorom в 1С.

Хуйнаныр(26)Очко(0)

Запостить высер

Стучать мне на мыло
avatar

Сортировать:   Свежие | Тухлые | Хуйнанырные
вася
робот-вертер
вася
10 месяцев 6 дней назад

Шикарно!

GlobalWhite
робот-вертер
GlobalWhite
4 месяцев 10 дней назад

order by rand() — вообще делать нельзя. Глупость космического масштаба, на самом деле. При большой базе, все равно упрется в запрос, даже если выборку делать только по айди. Идеальный вариант — посчитать количество товаров count(product_id), и потом сделать limit x,x+y — где Х = rand(x-y), а y — сколько рандомных товаров показать.

GlobalWhite
робот-вертер
GlobalWhite
4 месяцев 10 дней назад

Конечно же, rand не от x-y а от count(product_id)-y. И limit x, y а не x,x+y :)

wpDiscuz