0

このクエリを最適化したい。テーブルの使用に関する統計を提供しました。

productsproducts_categoriesテーブルには約500000のレコードがあります。ただし、後述のcategory場合、1600件のレコードがあります。この 1600 レコード用のスロットを作成しました。すべてproductに最小 1 スロット、最大 10 スロットを設定できます。しかし、スロット テーブルには約 300000 のレコードがあります。slot tableすでに期限切れのスロットを持つこともできます。もうすぐ賞味期限が切れる商品が先に来て、残りの商品はこの商品の後ろに来るようにしたいです。

end_time列のインデックスを作成しました。ただし、条件演算子を使用したため、このクエリではインデックスを使用していません。このクエリを最適化したい。最善の方法を教えてください。

EXPLAIN
SELECT
  xcart_products.*
FROM xcart_products
  INNER JOIN xcart_products_categories
    ON xcart_products_categories.productid = xcart_products.productid
  LEFT JOIN (SELECT
           t1.*
         FROM bvira_megahour_time_slot t1
           LEFT OUTER JOIN bvira_megahour_time_slot t2
         ON (t1.product_id = t2.product_id
             AND t1.end_time > t2.end_time
             AND t1.end_time > NOW())
         WHERE t2.product_id IS NULL) as bvira_megahour_time_slot
    ON bvira_megahour_time_slot.product_id = xcart_products.productid
WHERE xcart_products_categories.categoryid = '4410'
    AND xcart_products.saleid = 2
GROUP BY xcart_products.productid

以下は、説明クエリの結果です。

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   PRIMARY    xcart_products_categories    ref     PRIMARY,cpm,productid,orderby,pm    cpm     4   const   1523    Using index; Using temporary; Using filesort
1   PRIMARY     xcart_products  eq_ref  PRIMARY,saleid  PRIMARY     4   wwwbvira_xcart.xcart_products_categories.productid  1   Using where
1   PRIMARY     <derived2>  ALL     NULL    NULL    NULL    NULL    77215   
2   DERIVED     t1  ALL     NULL    NULL    NULL    NULL    398907  
2   DERIVED     t2  ref     i_product_id,i_end_time     i_product_id    4   wwwbvira_xcart.t1.product_id    4   Using where; Not exists
4

1 に答える 1

0

私はあなたの質問を次のように書き直しました:

EXPLAIN
SELECT p.*
FROM xcart_products p
INNER JOIN xcart_products_categories c
    ON c.productid = p.productid
LEFT JOIN (
    SELECT t1.*
    FROM bvira_megahour_time_slot t1
    LEFT JOIN bvira_megahour_time_slot t2
      ON (   t1.product_id = t2.product_id
         AND t1.end_time   > t2.end_time
         AND t1.end_time   > NOW()
      )
    WHERE t2.product_id IS NULL
) AS bvira_megahour_time_slot
  ON bvira_megahour_time_slot.product_id = p.productid
WHERE c.categoryid = '4410'
  AND p.saleid = 2
GROUP BY p.productid

次の複合 (複数列) インデックスがあることを確認してください。

bvira_megahour_time_slot:  (product_id, end_time)
xcart_products:            (productid, sale_id)
xcart_products_categories: (productid, category_id)
                        or (category_id, productid)

これらのインデックスを使用すると、はるかにうまく機能するはずです。

于 2013-01-30T06:43:40.747 に答える