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 回答