[英]Prestashop search slow after migrating from MySQL to MariaDB
將Prestashop實例從MySQL遷移到MariaDB后,過濾的搜索查詢變得很慢。 這是一個如此緩慢的查詢的示例。
SELECT
fl.name feature_name,
fp.id_feature,
fv.id_feature_value,
fvl.value,
COUNT(DISTINCT p.id_product) nbr,
lifl.url_name name_url_name,
lifl.meta_title name_meta_title,
lifvl.url_name value_url_name,
lifvl.meta_title value_meta_title,
psi.price_min,
psi.price_max,
m.name
FROM
ps_feature_product fp
INNER JOIN
ps_product p
ON
(p.id_product = fp.id_product)
LEFT JOIN
ps_feature_lang fl
ON
(
fl.id_feature = fp.id_feature AND fl.id_lang = 2
)
INNER JOIN
ps_feature_value fv
ON
(
fv.id_feature_value = fp.id_feature_value AND(
fv.custom IS NULL OR fv.custom = 0
)
)
LEFT JOIN
ps_feature_value_lang fvl
ON
(
fvl.id_feature_value = fp.id_feature_value AND fvl.id_lang = 2
)
LEFT JOIN
ps_layered_indexable_feature_lang_value lifl
ON
(
lifl.id_feature = fp.id_feature AND lifl.id_lang = 2
)
LEFT JOIN
ps_layered_indexable_feature_value_lang_value lifvl
ON
(
lifvl.id_feature_value = fp.id_feature_value AND lifvl.id_lang = 2
)
INNER JOIN
ps_product_shop product_shop
ON
(
product_shop.id_product = p.id_product AND product_shop.id_shop = 1
)
INNER JOIN
`ps_layered_price_index` psi
ON
(
psi.id_product = p.id_product AND psi.id_currency = 2 AND psi.id_shop = 1
)
LEFT JOIN
`ps_manufacturer` m
ON
(
m.id_manufacturer = p.id_manufacturer
)
WHERE
product_shop.`active` = 1 AND product_shop.`visibility` IN("both", "catalog") AND fp.id_feature = 9 AND p.id_product IN(
SELECT
id_product
FROM
ps_category_product cp
INNER JOIN
ps_category c
ON
(
c.id_category = cp.id_category AND c.id_category = 13 AND c.active = 1
)
) AND p.id_product IN(
SELECT
id_product
FROM
ps_feature_product fp
WHERE
fp.`id_feature_value` = 39
) AND p.id_product IN(
SELECT
id_product
FROM
ps_feature_product fp
WHERE
fp.`id_feature_value` = 18
) AND p.id_product IN(
SELECT
id_product
FROM
ps_feature_product fp
WHERE
fp.`id_feature_value` = 13
) AND p.id_product IN(
SELECT
id_product
FROM
ps_feature_product fp
WHERE
fp.`id_feature_value` = 44
) AND p.id_product IN(
SELECT
id_product
FROM
ps_feature_product fp
WHERE
fp.`id_feature_value` = 3186
)
GROUP BY
fv.id_feature_value
ORDER BY
fv.position
有趣的是,如果刪除了WHERE子句中的多個(幾乎相同)子查詢之一,它將獲得更快的速度(4s比0.4s)。
... AND
/*
-- removing any of the six product filters makes
-- the query a lot faster
p.id_product IN(
SELECT
id_product
FROM
ps_feature_product fp
WHERE
fp.`id_feature_value` = 18
)
*/
AND ...
這是此查詢的EXPLAIN輸出(不做任何修改)。
是否有明顯的東西需要以某種方式進行更改? 所有表都已經過優化,沒有任何改進。
您有以下幾種:
AND p.id_product IN (
SELECT id_product
FROM ps_feature_product fp
WHERE fp.`id_feature_value` = 39 )
可以變成這個
AND EXISTS ( SELECT * FROM ps_feature_product
WHERE id_product = p.id_product
AND id_feature_value = 39 )
IN ( SELECT ... )
的優化不佳。
確保具有INDEX(id_product, id_feature_value)
。
MySQL和MariaDB在性能上有所差異的原因是,一些優化改進在5.6中有所不同。 它們涉及與您正在做的事情有關的東西。
像
LEFT JOIN ps_layered_indexable_feature_value_lang_value lifvl
ON ( lifvl.id_feature_value = fp.id_feature_value
AND lifvl.id_lang = 2
需要一個復合INDEX(id_feature_value, id_lang)
(以任何順序)。 但我能猜到從EXPLAIN
,你有這樣的。
請為每個表提供SHOW CREATE TABLE
,可能會有更多建議。
我無法解決您的特定問題,因為我不知道EXPLAIN
哪一行與EXPLAIN
子句相對應。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.