如何加快查询速度?

时间:2011-04-11 19:45:54

标签: mysql

如何加快此查询?我使用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

我尝试添加不同的索引,但我的查询不想使用它们中的任何一个。任何帮助,将不胜感激。

4 个答案:

答案 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)

(日期,状态)上的复合索引应该使您的查询变得活泼。