慢查询,我应该索引还是其他解决方案?

时间:2013-04-03 07:06:11

标签: mysql

我有这个非常慢的查询,它计算具有特定规格的产品,是解决方案索引吗?或其他解决方案?

select count(DISTINCT if(ps10.specification in ('Meisje'),p.products_id,NULL)) as count1 ,count(DISTINCT if(ps10.specification in ('Jongen'),p.products_id,NULL)) as count2 ,count(DISTINCT if(ps10.specification in ('Unisex'),p.products_id,NULL)) as count3  from (products p)
                        join (products_to_categories p2c)
                          on (p.products_id = p2c.products_id)
                        left join (specials s)
                          on (p.products_id = s.products_id)
                        left join (products_attributes pa)
                          on (p.products_id = pa.products_id)
                        left join (products_options_values pv)
                          on (pa.options_values_id = pv.products_options_values_id)
                        left join (products_stock ps)
                          on (p.products_id=ps.products_id and pv.products_options_values_id = ps.products_options_values_id2)        
                                             INNER JOIN products_specifications ps10 ON p.products_id = ps10.products_id  INNER JOIN products_specifications ps17 ON p.products_id = ps17.products_id  where p.products_status = '1' and ps.products_stock_quantity>0   and p2c.categories_id in (2,54,60,82,109,115,116,118,53,58,104,55,101,75,56,64,66,67,68,69,70,71,84,103,114,80,92,99,93,94,95,97,106)  AND ps10.specifications_id = '10'
                  AND ps10.language_id = '1'
                   AND ps17.specification in ('Babyslofjes'
                              ) AND ps17.specifications_id = '17'
                  AND ps17.language_id = '1'

解释这个查询给了我这个结果:

+----+-------------+-------+--------+-------------------------------------+-------------------------------------+---------+------------------------------------------+-------+--------------------------+
| id | select_type | table |  type  |            possible_keys            |                 key                 | key_len |                   ref                    | rows  |          Extra           |
+----+-------------+-------+--------+-------------------------------------+-------------------------------------+---------+------------------------------------------+-------+--------------------------+
|  1 | SIMPLE      | ps    | ALL    | idx_products_stock_attributes       | NULL                                | NULL    | NULL                                     | 16216 | Using where              |
|  1 | SIMPLE      | p     | eq_ref | PRIMARY                             | PRIMARY                             | 4       | kikleding.ps.products_id                 |     1 | Using where              |
|  1 | SIMPLE      | s     | ref    | idx_specials_products_id            | idx_specials_products_id            | 4       | kikleding.p.products_id                  |     1 | Using index              |
|  1 | SIMPLE      | p2c   | ref    | PRIMARY                             | PRIMARY                             | 4       | kikleding.ps.products_id                 |     1 | Using where; Using index |
|  1 | SIMPLE      | pv    | ref    | PRIMARY                             | PRIMARY                             | 4       | kikleding.ps.products_options_values_id2 |     1 | Using where; Using index |
|  1 | SIMPLE      | ps10  | ref    | products_id                         | products_id                         | 12      | kikleding.p.products_id,const,const      |     1 | Using where              |
|  1 | SIMPLE      | ps17  | ref    | products_id                         | products_id                         | 12      | kikleding.ps.products_id,const,const     |     1 | Using where              |
|  1 | SIMPLE      | pa    | ref    | idx_products_attributes_products_id | idx_products_attributes_products_id | 4       | kikleding.p2c.products_id                |     6 | Using where              |
+----+-------------+-------+--------+-------------------------------------+-------------------------------------+---------+------------------------------------------+-------+--------------------------+

将左连接更改为内部连接,如下所示:

select count(DISTINCT if(ps10.specification in ('Meisje'),p.products_id,NULL)) as count1 ,count(DISTINCT if(ps10.specification in ('Jongen'),p.products_id,NULL)) as count2 ,count(DISTINCT if(ps10.specification in ('Unisex'),p.products_id,NULL)) as count3  from (products p)
                        inner join (products_to_categories p2c)
                          on (p.products_id = p2c.products_id)
                        left join (specials s)
                          on (p.products_id = s.products_id)
                        inner join (products_attributes pa)
                          on (p.products_id = pa.products_id)
                        inner join (products_options_values pv)
                          on (pa.options_values_id = pv.products_options_values_id)
                        inner join (products_stock ps)
                          on (p.products_id=ps.products_id and pv.products_options_values_id = ps.products_options_values_id2)        
                                             INNER JOIN products_specifications ps10 ON p.products_id = ps10.products_id  INNER JOIN products_specifications ps17 ON p.products_id = ps17.products_id  where p.products_status = '1' and ps.products_stock_quantity>0   and p2c.categories_id in (2,54,60,82,109,115,116,118,53,58,104,55,101,75,56,64,66,67,68,69,70,71,84,103,114,80,92,99,93,94,95,97,106)  AND ps10.specifications_id = '10'
                  AND ps10.language_id = '1'
                   AND ps17.specification in ('Babyslofjes'
                              ) AND ps17.specifications_id = '17'
                  AND ps17.language_id = '1'

我索引了ps.products_id

它快一点,谢谢你的评论,但查询仍然很慢

2 个答案:

答案 0 :(得分:0)

显然使用p.products_id更多,所以首先索引表Products中的属性。然后pv.products_options_values_id并尝试索引您在Inner Join中使用的其他属性。还尝试转换在Join条件中使用的条件特别适用于Inner join

答案 1 :(得分:0)

我会稍微修改一下查询,将条件从where部分放入连接中,从样本中我认为你也可以摆脱Specials表。

select
  count(distinct if(ps10.specification in ('Meisje'), p.products_id, null)) as count1,
  count(distinct if(ps10.specification in ('Jongen'), p.products_id, null)) as count2,
  count(distinct if(ps10.specification in ('Unisex'), p.products_id, null)) as count3
from (products p)
  inner join (products_to_categories p2c)
    on (p.products_id = p2c.products_id)
  inner join (products_attributes pa)
    on (p.products_id = pa.products_id)
  inner join (products_options_values pv)
    on (pa.options_values_id = pv.products_options_values_id)
  inner join (products_stock ps)
    on (p.products_id=ps.products_id and pv.products_options_values_id = ps.products_options_values_id2 and ps.products_stock_quantity > 0)        
  inner join products_specifications ps10
    ON p.products_id = ps10.products_id and ps10.language_id = '1' and ps10.specifications_id = '10'
  inner join products_specifications ps17
    ON p.products_id = ps17.products_id and ps17.language_id = '1' and ps17.specifications_id = '17'
where p.products_status = '1'
  and p2c.categories_id in (2,54,60,82,109,115,116,118,53,58,104,55,101,75,56,64,66,67,68,69,70,71,84,103,114,80,92,99,93,94,95,97,106)
  and ps17.specification in ('Babyslofjes')

至于索引,我会检查以下内容:

  • products / products_id(很可能是)
  • products_to_categories / products_id + categories_id(很可能也是)
  • products_attributes / products_id + options_values_id
  • products_options_values / products_options_values_id
  • products_specifications / products_id + language_id + specifications_id

从表名中我怀疑这是一个OS / XTcommerce数据库,我会尝试在几个小时内拿到一个并提供更详细的意见。我只是不记得products_stock和products_specifications,那些都是表,而不是视图,对吗?