- Прафіляванне запытаў да базе даных
- Прафіляванне PHP VirtueMart інструментам XHprof
- Аптымізацыя VirtueMart: вынікі
- Аптымізацыя VirtueMart: дапрацоўкі
Стаяла задача аптымізацыі VirtueMart. Тармазіла вітрына тавараў. Спачатку падазрэнне клалася на базу дадзеных.
Прафіляванне запытаў да базе даных
прафіляванне перконой не выявіла нічога крымінальнага:
# Overall: 38 total, 16 unique, 0 QPS, 0x concurrency ____________________ # Attribute total min max avg 95% stddev median # ============ ======= ===== == ======= ======= ======= ======= ======= # Exec time 405ms 10ms 11ms 11ms 11ms 364us 10ms # Lock time 0 0 0 0 0 0 0 # Rows sent 0 0 0 0 0 0 0 # Rows examine 0 0 0 0 0 0 0 # Query size 15.76k 39 738 424.82 719.66 255.28 487.09
Агульны аб'ём усіх адказаў базы дадзеных - 15.76k, мінімум 39 байт, максімум - 738, час выканання - 405 мілісекунд, мінімум - 10 мс, максімум - 11.
Дадзеныя атрыманыя без выкарыстання кэшу запытаў, у іх не патрапілі «хуткія» запыты, якія выконваюцца менш 0,01 сек.
0,4 секунды на базу дадзеных - гэта, вядома, шмат. Трэба імкнуцца, каб на ўсю старонку трацілася не больш 0,2 сек.
Самі запыты досыць хуткія, у аптымізацыі асаблівай неабходнасці няма. Яны бяруць «колькасцю».
У сітуацыі, калі на адкрыццё старонкі патрабуецца 3 секунды, тормазы з базай дадзеных у 0,4 сек - не самае вузкае месца. З «прагрэвам» кэшу запытаў гэты час істотна зменшыцца.
Астатнія паказчыкі ў норме. Няма занадта «доўгіх» запытаў.
Прафіляванне PHP VirtueMart інструментам XHprof
Вышэй - вынікі прафіляванне VirtueMart 2.0.20b з дапамогай XHprof . Зроблена прафіляванне старонкі вітрыны тавараў.
Час выканання - 1,1 сек, з уключаным кэшам запытаў, як на дзеючым сайце.
Пасля выбаркі прадуктаў па ўмове getProductListing, у скрыпце па кожнаму прадукту ідзе падгрузка дэталёвай інфармацыі getProductSingle.
Гэта займае 50% часу (IWall), прычым гэты працэс запускаецца для кожнага прадукту - разам 126 раз (Calls).
Кожны выклік метаду getProductSingle робіць пяць запытаў да БД (па коду) => 630 запытаў. На малюнку 1737 - агульная колькасць на ўсю старонку.
База дадзеных з такой колькасцю запытаў VirtueMart спраўляецца лёгка - усяго 10% агульнага часу (mysqli_query). Дзякуй кешью!
Правільна павінна быць зроблена так: адзін раз атрымліваецца ўся інфармацыя па выбраных прадуктам, потым яна раскідваецца. Так абыходзяцца пяццю запытамі.
Аптымізацыя VirtueMart: вынікі
VirtueMart тармозіць за кошт няправільнай рэалізацыі атрымання спісу тавараў, якасць гэтага кода пакідае жадаць лепшага. Паскарэнне ў працы з базай дадзеных нічога не прынясе.
Тры варыянты:
Аптымізацыя VirtueMart: дапрацоўкі
Ад версіі да версіі можа адрознівацца. Вось мой выпадак:
administrator / components / com_virtuemart / models / product.php
public function getProduct ($ virtuemart_product_id = NULL, $ front = TRUE, $ withCalc = TRUE, $ onlyPublished = TRUE, $ quantity = 1, $ customfields = TRUE, $ virtuemart_shoppergroup_ids = 0) {if (true &&! empty ($ Virtuemart_product_id) && $ front && JFactory :: getConfig () -> get ( 'caching')> = 1) {if (! class_exists ( 'CurrencyDisplay')) {require (JPATH_VM_ADMINISTRATOR. DS. 'Helpers'. DS. 'Currencydisplay.php'); // else 503 error} if ($ virtuemart_shoppergroup_ids! = 0 and is_array ($ Virtuemart_shoppergroup_ids)) {$ virtuemart_shoppergroup_idsString = implode ( '', $ Virtuemart_shoppergroup_ids); } Else {$ virtuemart_shoppergroup_idsString = $ virtuemart_shoppergroup_ids; } $ WithRating = $ this -> withRating? TRUE: 0; $ ProductKey = $ virtuemart_product_id. '-'. $ Front. '-'. $ WithCalc. '-'. $ OnlyPublished. '-'. $ Quantity. '-'. $ Customfields. '-'. $ Virtuemart_shoppergroup_idsString. '-'. $ WithRating; $ Mycache = JFactory :: getCache ( 'com_virtuemart_speedup', ''); $ Mycache -> setLifeTime (86400); $ Cache_content = $ mycache -> get ($ productKey); if (! is_object ($ Cache_content)) {$ cache_content = $ this -> _getProduct ($ virtuemart_product_id, $ front, $ withCalc, $ onlyPublished, $ quantity, $ customfields, $ virtuemart_shoppergroup_ids); $ Mycache -> store ($ cache_content, $ productKey); } Return $ cache_content; } Else {return $ this -> _getProduct ($ virtuemart_product_id, $ front, $ withCalc, $ onlyPublished, $ quantity, $ customfields, $ virtuemart_shoppergroup_ids); }} Public function _getProduct ($ virtuemart_product_id = NULL, $ front = TRUE, $ withCalc = TRUE, $ onlyPublished = TRUE, $ quantity = 1, $ customfields = TRUE, $ virtuemart_shoppergroup_ids = 0) {// тут стары варыянт функцыі _getProduct}