如何加快此查询?我使用MySQL 5.1,表'schedule'有~900 K行,我的查询运行时间超过分钟:
SELECT doc_code, `DATE`, time2, pat_code, STATUS,
copiedto1, copiedto2, copiedto3, copiedto4, copiedto5
FROM SCHEDULE
WHERE 1=1
AND STATUS IN (5,6,30)
AND (doc_code="K9" OR copiedto1="K9" OR copiedto2="K9"
OR copiedto3="K9" OR copiedto4="K9" OR copiedto5="K9")
AND `date` BETWEEN "2010/04/11" AND "2011/04/11"
AND pat_code > 0
ORDER BY `date`, doc_code, time2
我尝试添加不同的索引,但我的查询不想使用它们中的任何一个。任何帮助,将不胜感激。
答案 0 :(得分:1)
我会把它改成
SELECT s.* FROM (
SELECT doc_code, `DATE`, time2, pat_code, STATUS,
copiedto1, copiedto2, copiedto3, copiedto4, copiedto5
FROM SCHEDULE
WHERE STATUS IN (5,6,30)
AND `date` BETWEEN "2010/04/11" AND "2011/04/11"
AND pat_code > 0
ORDER BY `date`, doc_code, time2 ) s
WHERE (s.doc_code="K9" OR s.copiedto1="K9" OR s.copiedto2="K9"
OR s.copiedto3="K9" OR s.copiedto4="K9" OR s.copiedto5="K9")
在MySQL文档的深处,我记得读过一些关于OR
使用索引的内容。
我有一种感觉正在发生
如果您首先使用所有AND
进行查询以限制记录数量
然后使用OR
进行选择我希望您的查询运行得更快。
修改强>
http://forge.mysql.com/wiki/Top10SQLPerformanceTips 说:避免在索引字段上使用IN,它会导致性能下降 无论如何,有很多选择标准,查询优化器不知道从哪里开始 请注意,如果查询优化器“认为”标准将使用超过25-50%的(我忘记了所有字段的确切百分比),则不会使用任何索引。
或者你可以使用
SELECT s.* FROM (
SELECT doc_code, `DATE`, time2, pat_code, STATUS,
copiedto1, copiedto2, copiedto3, copiedto4, copiedto5
FROM SCHEDULE
USE INDEX (someIndex,someOtherIndex) #<<<<-------------
WHERE STATUS IN (5,6,30)
AND `date` BETWEEN "2010/04/11" AND "2011/04/11"
AND pat_code > 0
ORDER BY `date`, doc_code, time2 ) s
WHERE (s.doc_code="K9" OR s.copiedto1="K9" OR s.copiedto2="K9"
OR s.copiedto3="K9" OR s.copiedto4="K9" OR s.copiedto5="K9")
索引名称或不等于索引索引的字段名称
您可以在表的create语句中找到索引名称,也可以在explain select
附带的explain输出中找到索引名称。
请注意强制索引,在最终确定之前进行测量 并且记住,当表中的数据发生变化时,现在快速运行的强制索引查询可能会运行缓慢。
答案 1 :(得分:0)
这是非常优化的,您是否为WHERE子句中的所有列编制索引?
您可以通过预先填充仅包含K9代码的schedule_k9表或仅具有pat_codes&gt;的表来尝试分阶段进行查询。 0
答案 2 :(得分:0)
SELECT doc_code, DATE, time2, pat_code, STATUS, copiedto1, copiedto2, copiedto3, copiedto4, copiedto5
FROM SCHEDULE
AND (doc_code="K9" OR copiedto1="K9" OR copiedto2="K9" OR copiedto3="K9" OR copiedto4="K9" OR copiedto5="K9")
AND pat_code > 0
AND `date` BETWEEN "2010/04/11" AND "2011/04/11"
AND STATUS IN (5,6,30)
ORDER BY `date`, doc_code, time2
我必须看到你的表的一个样本,以进一步改进查询(因为可能有很多行具有某种模式等...)
您可以使用不同类型的mysql数据库。一些具有更好的读取速度,另一些具有更好的写入速度。这是一篇关于mysql数据库类型的好文章:here
我建议您使用MyISAM表类型。不幸的是,它不适用于索引。您可以通过以下方式更改表的格式:
ALTER TABLE SCHEDUALE CHANGE TYPE=MyISAM
答案 3 :(得分:0)
(日期,状态)上的复合索引应该使您的查询变得活泼。