簡體   English   中英

從MySQL遷移到MariaDB后,Prestashop搜索變慢

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM