需要优化mysql查询

时间:2013-01-30 06:16:08

标签: mysql optimization

我想优化此查询。我已经提供了使用表格的统计数据。

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

1 个答案:

答案 0 :(得分: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)

使用这些索引,它应该可以更好地工作。