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 のインデックスを作成しました

コメントに感謝しますが、クエリはまだ非常に遅いです

4

2 に答える 2

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 データベースであると思われます。数時間後に 1 つを手に入れて、より詳細な意見を述べるつもりです。私はproducts_stockとproducts_specificationsを覚えていません.これらは両方ともテーブルであり、ビューではありません.

于 2013-04-03T10:02:38.297 に答える
0

明らかなように、p.products_id を使用するので、最初にテーブル Products のその属性にインデックスを付けます。次に、pv.products_options_values_id を実行し、内部結合で使用する他の属性のインデックスも作成します。また、特に内部結合の結合条件で使用する場所の条件を変換してみてください

于 2013-04-03T07:10:40.797 に答える