2012-06-19 31 views
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); 

的说明:

Explain commands result

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

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

+0

如果您使用“show creeate table X”为我们提供表格定义,将会有所帮助。 –

+0

你是什么意思'但我仍然得到查询锁由于这个查询' – Kshitij

+0

每当这个查询被执行,它需要很多时间和进程状态显示“发送数据” –

回答

1

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

如您的EXPLAIN所示,表AA表中找不到合适的密钥,必须扫描所有534956行以满足WHERE子句。

最后一条提示:对主键使用大列类型(如VARCHAR(60))可能不是最优的。

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

原因二:对字符串比较是比整数慢(因此它可以呈现超过必要慢JOIN

您可能希望将INT列添加到您的表格,并把它作为主键。

+0

问题是所有三个标志( AA.stdsign,AA.ivaflag和AA.opts)只能有3个不同的值。这些列的索引会减少查询时间吗? –

+2

是的,它会的。无论有两个,三个还是一千个不同的值,MySQL仍然需要找出哪些行符合您的条件。没有索引,它没有其他解决方案,但扫描整个表。 – RandomSeed