CS-Cart 3 фиксим медленный запрос
Недавно мне пришлось вернуться к этому вопросу т.к. с возросшей нагрузкой на сайт игнорировать этот медленный запрос уже не получилось. Пришлось погружаться в дебри EXPLAIN’ов. Итак, результаты анализа показали что тот многоэтажный запрос создает временную таблицу размером в 2Gb и дергает из таблицы с характеристиками 300к записей чем делает грустно MySQL-серверу. Причем что 10 товаров, что 100 - в любом случае дергается 300к записей (все что есть).
Все происходит в недрах километровой функции fn_get_products в /core/fn.catalog.php
1 | $products = db_get_array("SELECT SQL_CALC_FOUND_ROWS " . implode(', ', $fields) . " FROM ?:products as products $join WHERE 1 $condition GROUP BY $group_by ORDER BY $sorting $limit"); |
Эта казалось бы безобидная строчка превращается в многоэтажный SQL-запрос. Который впрочем выполняется довольно быстро. если не одно но:
1 | ... LEFT JOIN (SELECT product_id, GROUP_CONCAT(?:product_features_values.variant_id) AS advanced_variants FROM ?:product_features_values WHERE lang_code = 'RU' GROUP BY product_id) AS pfv_advanced ON pfv_advanced.product_id = products.product_id ... |
Что можно исправить убрав лишний JOIN и изменив условие в WHERE на:1
AND products.product_id IN (SELECT product_id FROM cscart_product_features_values WHERE variant_id=... AND lang_code='RU')
Лично я не нашел ничего лучше чем регуляркой выявлять этот злобный запрос и опять же регуляркой его изменять на добрый.
Результаты на моем ноутбуке и MySQL 5.6 с дефолтными настройками:
Выполнение запроса 0.5 сек против 7 сек
Теперь графики Munin стали ровнее и с меньшими значениями LA, а мои волосы стали гладкими и шелковистыми.