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 );

解释:

解释命令结果

一种方法是索引所有 3(AA.stdsign、AA.ivaflag 和 AA.opts)列,但所有三个标志(AA.stdsign、AA.ivaflag 和 AA.opts)只能有 3 个不同的值。索引这些会减少查询运行时间?

所有的 id 都是 varchar(60) 数据类型。

4

1 回答 1

1

查询本身没有太多需要改进的地方。另一方面,在AA.stdsign, AA.ivaflagand上设置索引AA.opts应该会有很大帮助。

正如您所EXPLAIN指出的,没有为您的表找到合适的键,AA并且必须扫描所有 534956 行以满足该WHERE子句。

[编辑] 最后一个提示:对主键使用大列类型(例如VARCHAR(60))可能不是最佳选择。

第一个原因:每次您需要引用一行(例如在外键中)时,您都需要另一个VARCHAR(60).

第二个原因:字符串的比较比整数慢(因此它可能会JOIN比必要的慢)

您可能希望向INT表中添加一列,并将其用作主键。

于 2012-06-19T07:24:55.717 回答