В рамках цикла заметок по вычислению и снижению нагрузки на сервер было бы не правильно не опубликовать логическое завершение «разборок» с VirtueMart, как одним из виновников в жёстском ступоре сервера, выявленном по создаваемым нагрузкам на MySQL — подробнее в предыдущей заметке Вычисление нагрузки на сервер. Part 1 — MySQL Так же стоит заметить — торможение MySQL цепляет за собой и нагрузку на память в виде ожидающего данных веб-сервера (на данный момент у меня это сильно сжирающий память индеец).
Итак:
- изначально о слишком большой нагрузке узнал в реальном режиме просматривая top
- далее захотелось узнать кто же конретно грузит — с этой задачей справилась утилита mtop
- конкретные «тормозные» SQL запрос смотрим в логах, предварительно включив нужную опцию
Виновник вычислен, скрипт известен — что же дальше ?
Ну а дальше самый важный шаг — оптитизация приложения.
Грамотно реализованное приложение будет работать быстрее аналогичного по задачам на обычном VDS против супер-навороченного выделенного сервера — это факт !
Ладно — хватит лирики .. .По нашей задаче — далее всеми мыслимыми и немыслимыми способами ищем программный код, генерирующий вычисленный запрос — гуглим, разбираемся в Joomla, VitueMart, ищем по «select distinct», включаем интуицию, метод «научного тыка» — в общем все эти «пляски с бубном» лично мне помогли вычислить файл — shop_browse_queries.php
Далее анализируем и оптимизируем сам запрос — вычисляем неиспользуемые и ненужные поля — убираем их, проверям заново (всё это можно делать отдельно от приложения — например, в чистом MySQL.
Далее дело за малым — правим наш shop_browse_queries.php в соответствие с нашим запросом.
Всё ! В результате проделанных махинаций запрос стал отрабатывать раз в 10 быстрее, в лог «тормозов» не попадает — сервер вздохнул свободно (по крайней мере падений пока не наблюдалось).
Кому интересно, вот подробности:
Мой файлик после корректировки
Вычисленный запрос
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
SELECT DISTINCT `product_name`,`products_per_row`,`category_browsepage`,`category_flypage`,`jos_vm_category`.`category_id`, `jos_vm_product`.`product_id`,`product_full_image`,`product_thumb_image`,`product_s_desc`,`product_parent_id`,`product_publish`,`product_in_stock`,`product_sku`, `product_url`, `product_weight`,`product_weight_uom`,`product_length`,`product_width`,`product_height`,`product_lwh_uom`,`product_in_stock`,`product_available_date`,`product_availability`,`jos_vm_product`.`mdate`, `jos_vm_product`.`cdate` FROM (`jos_vm_product`, `jos_vm_category`, `jos_vm_product_category_xref`,`jos_vm_shopper_group`) LEFT JOIN `jos_vm_product_price` ON `jos_vm_product`.`product_id` = `jos_vm_product_price`.`product_id` WHERE (`jos_vm_product_category_xref`.`product_id`=`jos_vm_product`.`product_id` OR `jos_vm_product_category_xref`.`product_id`=`jos_vm_product`.`product_parent_id`) AND `jos_vm_product_category_xref`.`category_id`=`jos_vm_category`.`category_id` AND `jos_vm_product_category_xref`.`category_id`=19 AND ((`jos_vm_product`.`product_id`=`jos_vm_product_price`.`product_id` AND `jos_vm_shopper_group`.`shopper_group_id`=`jos_vm_product_price`.`shopper_group_id`) OR `jos_vm_product_price`.`product_id` IS NULL) AND `jos_vm_shopper_group`.`default` = 1 AND `product_parent_id`=0 AND `product_publish`=‘Y’ AND `category_publish`=‘Y’ GROUP BY `jos_vm_product`.`product_sku` ORDER BY `jos_vm_product`.`product_name` ASC LIMIT 0, 20 |
Запрос после модификации (внимание — подобное вырезание, конечно же вырезает и функционал, я просто многое не использую — поэтому порезал. так что «7 раз отмерь 1 отреж»)
1 2 3 4 5 6 7 8 9 10 11 |
SELECT DISTINCT `product_name`,`jos_vm_category`.`category_id`,`jos_vm_product`.`product_id`,`product_full_image`,`product_thumb_image`,`product_s_desc`,`product_publish`,`product_sku`, `product_weight`,`product_weight_uom`,`jos_vm_product`.`mdate`, `jos_vm_product`.`cdate` FROM (`jos_vm_product`, `jos_vm_category`, `jos_vm_product_category_xref`,`jos_vm_shopper_group`) LEFT JOIN `jos_vm_product_price` ON `jos_vm_product`.`product_id` = `jos_vm_product_price`.`product_id` WHERE `jos_vm_product_category_xref`.`product_id`=`jos_vm_product`.`product_id` AND `jos_vm_product_category_xref`.`category_id`=`jos_vm_category`.`category_id` AND `jos_vm_product_category_xref`.`category_id`=19 AND `jos_vm_product`.`product_id`=`jos_vm_product_price`.`product_id` AND `product_publish`=‘Y’ GROUP BY `jos_vm_product`.`product_sku` ORDER BY `jos_vm_product`.`product_name` ASC LIMIT 0, 20 |
Статистика до (товаров в базе около 5k)
1 2 3 4 5 6 7 8 9 |
Информация о профиле Application afterLoad: 0.000 seconds, 0.44 MB Application afterInitialise: 0.061 seconds, 4.05 MB Application afterRoute: 0.069 seconds, 4.92 MB Application afterDispatch: 1.149 seconds, 16.96 MB Application afterRender: 1.877 seconds, 18.51 MB Использование памяти 19457648 Зарегистрировано запросов: 413 |
Статистика «после»
1 2 3 4 5 6 7 8 9 |
Информация о профиле Application afterLoad: 0.000 seconds, 0.45 MB Application afterInitialise: 0.047 seconds, 4.05 MB Application afterRoute: 0.055 seconds, 4.92 MB Application afterDispatch: 0.626 seconds, 16.96 MB Application afterRender: 0.701 seconds, 18.52 MB Использование памяти 19461440 Зарегистрировано запросов: 413 |
P.S. Следующим шагом будет полный отказ от Apache — переход на связку nginx+php as fastcgi
Что по идее должно сильно разгрузить память (если получится — можно на мускул будет побольше выделить).
17 комментариев на «“Снижение нагрузки на сервер. Оптимизация VitrueMart.”»
Как говорится скупой платит дважды.
Virtuemart писали школьники, так что ничего тут удивительного нет.
IMHO лучше сделать небольшое вложение как и в любом бизнесе и спасти свой мозг как минимум.
Но и выбирая платный продукт нужно быть осторожным(та же разработка «отечественных программистов» — phpshop — тупая поделка ясельной группы)
Ну а тем кто пожалел на вложение в инет-магазин, статья очень поможет (верней тем кто занимается разработкой для них).
Есть еще «Хак ускоряющий виртумарт как минимум в 10 раз».
Приведенная статистика не показательна. Примените вот такой хак — http://j-web.ru/stati/joomla-1-5/47-vremya-vypolneniya-zaprosov-v-debug-informaczii-i-mesto-vyzova-sql-zaprosa-v-joomla-15
и увидите сколько времени исполняется каждый запрос
Danik — ну посоветовал бы уже платный продукт.
Ссылочку на хак так же не помешало бы запостить.
Beagler — спасибо! классный хак
Спасибо. Сам как раз юзать начал виртмарт. Кстати, никто не знает, где можно приобрести псевдо магазины на виртмарте? Долларов за 15-20?
На самом важном шаге — можно споткнуться и все запороть.
главное не запутаться
Спасибо, полезная инфа…
Спасибо за статью загляните к нам.Всё для вашего сайта или блога, а также фильмы игры и многое другое http://4web.ucoz.net/
есть еще вариант сменить движок магазина))
Очень полезно молодцы
Во всем есть свои плюсы и минусы, «Следующим шагом будет полный отказ от Apache — переход на связку nginx+php as fastcgi» мне вот немного сомнительна успешность таких заявлений. У вас есть положительные примеры такого перехода?
добавил статью в закладки. полезная информация.
Интересная статья, помогла мне разобраться
Спасибо за развернутую статю с примером. Оказывается не все так уж и сложно.
Всегда напрягала тугость этого компонента… (та и сама джумла — не спринтер). Может ваш рецепт улучшит ситуацию. Опробую. Спасибо!
Вот пошел свой мебельный магазин http://optimmebel.ru оптимизировать, надеюсь все сработает как надо