1

このクエリを可能な限り最適化しようとしていますが、それでもこのクエリが原因でクエリロックが発生します。改善のための提案はありますか。クエリはテーブルから最後の1日のエントリをフェッチします。

質問:

SELECT CR.id,
       CR.servicecode,
       CR.leadtime,
       CR.redirecturl,
       CRE.custemail,
       CRE.custlname,
       CRE.custfname,
       CRE.duration,
       CR.userid,
       AA.lpintrotimearr,
       AA.lpintrotimedep,
       AA.landdatetimearr,
       AA.landdatetimedep,
       CR.newcustid,
       cre.CRE.custmobilephone,
       CRE.brandname
FROM   response CR
       LEFT JOIN agreement AA
              ON CR.id = AA.id
       LEFT JOIN request CRE
              ON CRE.id = CR.id
WHERE  CR.id > '20120617145243'
       AND CR.approved = 1
       AND CR.chlapproved != 0
       AND CR.chlapproved IS NOT NULL
       AND AA.id IS NOT NULL
       AND ( AA.stdsign != 'on'
              OR AA.stdsign IS NULL )
       AND ( AA.ivaflag = 0
              OR AA.ivaflag IS NULL )
       AND ( AA.opt IS NULL
              OR AA.opt = 0 );

説明:

コマンドの結果を説明する

1つの方法は、3つすべての(AA.stdsign、AA.ivaflag、およびAA.opts)列にインデックスを付けることですが、3つのフラグ(AA.stdsign、AA.ivaflag、およびAA.opts)はすべて3つの異なる値しか持つことができません。クエリ実行時?

すべてのIDはvarchar(60)データ型です。

4

1 に答える 1

1

クエリ自体に改善すべき点はあまりありません。一方、にインデックスを設定するとAA.stdsign、非常に役立ちます。AA.ivaflagAA.opts

EXPLAIN指摘のとおり、テーブルに適したキーが見つからないため、句AAを満たすために534956行すべてをスキャンする必要があります。WHERE

[編集]最後のヒント:主キーに大きな列タイプ(などVARCHAR(60))を使用することは、おそらく最適ではありません。

最初の理由:行を参照する必要があるたびに(たとえば、外部キーで)、別のが必要になりますVARCHAR(60)

2番目の理由:文字列の比較は整数よりも遅い(したがってJOIN、必要以上に遅くなる可能性があります)

INTテーブルに列を追加し、それを主キーとして使用することをお勧めします。

于 2012-06-19T07:24:55.717 に答える