これはログからの 2 番目のクエリで、他のクエリを調べています。これを支援するために、サブクエリを取り除くために少し再構築し、INNER JOIN に変えました。また、他の人があなたのテーブルを知らないのを助けるために、フィールド参照を常に table.column または alias.column として修飾して、level_depth、nleft、nright がどこから来ているかを知るようにしてください。インデックスに役立つ場合があります。
インデックスの場合、テーブルごとに次のようになります。
ps_category, index ON( active, id_category, id_lang, nleft, nright, level_depth )
ps_category_lang, index ON( id_category, id_shop, id_lang )
ps_category_shop, index ON( id_category, id_shop )
ps_category_group, index ON( id_category, id_group )
ps_lang, index ON( id_lang, active )
少し書き直したクエリ
SELECT
c.id_parent,
c.id_category,
cl.name,
cl.description,
cl.link_rewrite
FROM
ps_category c
INNER JOIN ps_category_lang cl
ON c.id_category = cl.id_category
AND cl.id_shop = 1
AND cl.id_lang = 2
INNER JOIN ps_category_shop cs
ON c.id_category = cs.id_category
AND cs.id_shop = 1
INNER JOIN ps_category_group psg
ON c.id_category = psg.id_category
AND psg.id_group = 1
WHERE
( c.active = 1
OR c.id_category = 2)
AND c.id_category != 1
AND level_depth <= 7
AND nleft >= 350 AND nright <= 351
ORDER BY
level_depth ASC,
cs.position ASC;
3 番目のクエリ。この場合、特定の重要な要素の一部が一番上に移動されていることに注意してください。したがって、キー インデックスにもそれらがあり、残りは where 句にあります (主に読みやすさの調整ですが、「特定の」要素を確認するのに役立ちます)インデックスの利点 )
SELECT
c.id_category,
cl.name,
cl.link_rewrite
FROM
ps_category c
LEFT JOIN ps_category_lang cl
ON c.id_category = cl.id_category
AND cl.id_shop = 1
INNER JOIN ps_category_shop category_shop
ON c.id_category = category_shop.id_category
AND category_shop.id_shop = 1
WHERE
c.active = 1
AND cl.id_lang = 2
AND c.nleft between 2 and 350
AND c.nright between 351 and 625
AND c.level_depth > 1
ORDER BY
c.level_depth ASC;
あなたが本当に望んでいたものを確認する必要がある次のクエリ...言語テーブルへの左結合がありますが、実際にはそれをINNERに変えるwhere句に「AND l.active = 1」を追加します加入。本当にLEFT-JOINにしたい場合は、ここで調整したように l.active を結合部分に移動します
SELECT
l.id_lang,
c.link_rewrite
FROM
ps_category_lang AS c
LEFT JOIN ps_lang AS l
ON c.id_lang = l.id_lang
AND l.active = 1
WHERE
c.id_category = 324
これらのインデックスとサンプルの明確化/クエリの読みやすさが、ログの改善に役立つことを願っています。それでも問題が解決しない場合は、必要に応じて投稿してください。
スロー ログ レポートの最初のクエリの改訂
最初のクエリでは、特定の製品ショップから商品を探しているようです。ただし、製品カテゴリからクエリを開始し、製品に左結合し、次に製品ショップに結合しています。これらの製品は最終的に where を介して特定のカテゴリに関連付けられるため、いずれにしても INNER JOIN が作成されます。以下のように少し再構築します
ps_product_shop ON ( id_shop, active, visibility, id_product, id_category_default ) に単一のインデックスを作成します。
SELECT
p.*,
ps.*,
stock.out_of_stock,
IFNULL(stock.quantity, 0) as quantity,
MAX(pas.id_product_attribute) id_product_attribute,
pas.minimal_quantity AS product_attribute_minimal_quantity,
pl.description,
pl.description_short,
pl.available_now,
pl.available_later,
pl.link_rewrite,
pl.meta_description,
pl.meta_keywords,
pl.meta_title,
pl.name,
MAX(image_shop.id_image) id_image,
il.legend,
m.name AS manufacturer_name,
cl.name AS category_default,
DATEDIFF(ps.`date_add`, DATE_SUB(NOW(),INTERVAL 20 DAY)) > 0 AS new,
ps.price AS orderprice
FROM
( select @thisLanguage := 1 ) sqlvars,
ps_product_shop ps
INNER JOIN ps_product p
ON ps.id_product = p.id_product
INNER JOIN ps_category_product cp
ON id_product = cp.id_product
AND cp.id_category = 2
LEFT JOIN ps_product_attribute pa
ON p.id_product = pa.id_product
LEFT JOIN ps_product_attribute_shop pas
ON pa.id_product_attribute = pas.id_product_attribute
AND ps.id_shop = pas.id_shop
AND pas.default_on = 1
LEFT JOIN ps_stock_available stock
ON p.id_product = stock.id_product
AND ps.id_shop = stock.id_shop
AND stock.id_shop_group = 0
AND stock.id_product_attribute = IFNULL(pas.id_product_attribute, 0)
LEFT JOIN ps_product_lang pl
ON p.id_product = pl.id_product
AND ps.id_shop = pl.id_shop
AND pl.id_lang = @thisLanguage
LEFT JOIN ps_image i
ON p.id_product = i.id_product
LEFT JOIN ps_image_shop image_shop
ON i.id_image = image_shop.id_image
AND ps.id_shop = image_shop.id_shop
AND image_shop.cover = 1
LEFT JOIN ps_image_lang il
ON image_shop.id_image = il.id_image
AND il.id_lang = @thisLanguage
LEFT JOIN ps_manufacturer m
ON p.id_manufacturer = m.id_manufacturer
LEFT JOIN ps_category_lang cl
ON ps.id_category_default = cl.id_category
AND cl.id_shop = ps.id_shop
AND cl.id_lang = @thisLanguage
WHERE
ps.id_shop = 1
AND ps.active = 1
AND ps.visibility IN ("both", "catalog")
GROUP BY
ps.id_product
ORDER BY
cp.position ASC
LIMIT
0,8;
複数フィールドのインデックスを単一のインデックスとして作成する場合は、次のようになります。
CREATE INDEX act_id_lang ON ps_category( active, id_category, id_lang, nleft, nright, level_depth );
簡単なインデックス名を付けます...どのテーブルでも...クエリで有効になるため、すべてのキーを使用します。