2016-07-01 15 views
0

に参加する私のsqlです:なぜSELECT COUNT()とても遅い。ここ

select count(*) 
from goods g 
left join goods_policy s 
     on g.com_uid = s.com_uid 
    AND g.goods_uid = s.goods_uid 
WHERE g.com_uid = '123' 

あり、各テーブル内の唯一の2000レコードがあるが、それは4秒以上かかります。 説明は以下である:

1 SIMPLE g ref AK_GOOD_CODE,GOODS_IDX_COM,GOODS_IDX_STATUS GOODS_IDX_COM 98 const 1272 Using where; Using index 
1 SIMPLE s ref PRIMARY PRIMARY 98 biz_1.g.COM_UID 2 Using where; Using index 

表goods_policy 3つのフィールド、com_uid、goods_uidとpolicy_uidテーブル商品がcom_uidたが、goods_uid及び商品自体についての他のフィールドを有しています。

内部結合を使用すると、同じ説明結果で0.01秒かかるだけです。

なぜ結合に時間がかかり、このSQLを改善できますか?

編集:ここでは は両方のテーブルの行です:

select count(*) from goods;2827 
select count(*) from GOODS_POLICY; 2729 

そして、ここでは、指標である:参加するためにそれを句と追加

goods 0 PRIMARY 1 GOODS_UID A 2544    BTREE  
goods 0 AK_GOOD_CODE 1 COM_UID A 14    BTREE  
goods 0 AK_GOOD_CODE 2 GOODS_CODE A 2544    BTREE  
goods 0 AK_GOOD_CODE 3 STATUS A 2544   YES BTREE  
goods 1 GOODS_IDX_COM 1 COM_UID A 14    BTREE  

goods_policy 0 PRIMARY 1 COM_UID A 1364    BTREE  
goods_policy 0 PRIMARY 2 POLICY_UID A 2729    BTREE  
goods_policy 0 PRIMARY 3 GOODS_UID A 2729    BTREE  
+0

LEFT JOINは 'goods'のすべての行をインクルードしますが、INNERは 'goods_policy'に一致する行のみをインクルードします。彼らは異なった質問です、そして、私は 'カウント 'がLEFTよりもはるかに大きいと推測しています。 – Uueerdo

+0

左ジョインでは、 "Count"は必ず商品テーブルのレコード数を返します。ジョインは何も変わりません。 –

+0

はい、ただし、各テーブルには2000行しかありません。どのようにして左結合を遅くすることができますか? – Cedric

答えて

0

削除それはその前にslectを実行します選択した結果セットのみに参加します。

select count(*) from goods g left join 
goods_policy s on s.com_uid = '123' AND 
g.goods_uid = s.goods_uid and g.com_uid = '123' 
+0

MySQLは通常、実際に結合する前にwhere句からそのような条件を使用するのに十分スマートです。 – Uueerdo

+0

はいそれは本当ですが、場合によっては明示的に言わなければなりません。これを試してみてください。 –

+0

私はこれを試してみましたが、うまくいきませんでした。 – Cedric

0

時間コンポジット索引その後

CREATE TABLE goods (
    ... 
    PRIMARY KEY (com_uid), 
    INDEX goods (com_uid , goods_uid) 
); 

CREATE TABLE goods_policy (
    ... 
    PRIMARY KEY (goods_uid), 
    INDEX goods_policy (com_uid , goods_uid) 
); 

も@Mahesh暗示してみてください

select count(*) 
from goods g 
left join goods_policy s 
     on g.com_uid = s.com_uid 
    AND g.goods_uid = s.goods_uid 
    AND g.com_uid = '123' 
+0

'LEFT JOIN'があるときに' WHERE'を 'ON'に動かすと意味が変わります。 'LEFT'を取り除くか、123を' WHERE'に戻してください。 –

0

goods_policyで再配置、:JOINをより効率的になります

PRIMARY KEY(com_uid, goods_uid, policy_uid) 

(しかし、それはあなたが正しいことを数えているかどうか言及していない、またLEFTが必要とされているかどうか。私は強く1を疑うまたは両方が間違っている。)

はさらにこれを議論する前に、SHOW CREATE TABLEを提供してください。

0

com_uid、policy_uidおよびgoods_uidにインデックスを追加することで、問題は解決しました。

関連する問題