2013-04-03 53 views
0

我有这个非常慢的查询,它计数具有一定规格的产品,是解决方案索引?或其他解决方案?缓慢的查询,我应该索引还是其他解决方案?

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

这是一点点快,谢谢你的意见,但查询仍然很慢

+0

也许你应该删除所有冗余的连接/表,并用第一个内部连接替换没有返回未连接行的左连接? – symcbean

+0

您在WHERE子句中检查ps.products_stock_quantity> 0。要做到这一点,你必须有一个匹配的ps记录,并得到你必须有pv和pa记录。所以把它们改成内连接。你有关于ps.products_id的索引吗? – Kickstart

+0

谢谢我把它改为内加入这样的: 内部连接(products_attributes PA) 上(p.products_id = pa.products_id) 内部连接(products_options_values PV) 上(pa.options_values_id = pv.products_options_values_id) 内加入(products_stock ps) 和索引ps.products_id,它有点快但仍然很慢 –

回答

0

由于明显使用p.products_id,所以首先在表产品中指定属性。然后pv.products_options_values_id并尝试为您在Inner Join中使用的其他属性编制索引。也尝试转换条件要在连接条件特别是内部连接

0

我会去稍作修改的查询将条件从哪里部分,从我认为你的样本也可以摆脱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_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,那些都是表格,而不是视图,对吗?

+0

略有修改,这是非常好的略有改善,谢谢你 –

+0

这是一个oscommerce数据库。 products_stock和product_specifications是来自已安装的contiibutions的表格 –