如何使PHP中的mysql查询运行得更快

时间:2013-09-30 11:03:18

标签: php mysql sql

我在一个有数千行的表上运行查询:

$sql="select * from call_history where extension_number = '0536*002' and flow = 'in' and DATE(initiated) = '".date("Y-m-d")."' ";

并且永远地回归结果。

SQL本身是

 select * 
   from call_history 
  where extension_number = '0536*002'
    and flow = 'in' 
    and DATE(initiated) = 'dateFromYourPHPcode'

有没有办法让它跑得更快?我应该将DATE(initiated) = '".date("Y-m-d")."'放在extension_number where子句之前吗?

或者我应该选择DATE(initiated) = '".date("Y-m-d")."'的所有行并将其放入while循环中,然后在while循环中运行所有其他查询(where extension_number = ...)

3 个答案:

答案 0 :(得分:1)

以下是一些建议:

1)将SELECT *替换为您想要的唯一字段。

2)在您想要输出的表字段上添加索引。

3)避免在循环中运行查询。这会导致对SQL Server的多个请求。

4)一次获取所有数据。

5)在需要时应用LIMIT标签。不要选择所有记录。

6)触发两个不同的查询:一个用于计算记录总数,另一个用于获取每页记录数(例如10,20,50等等)

7)如果适用,创建数据库视图并从中获取数据而不是表。 感谢

答案 1 :(得分:1)

WHERE下的条款顺序与优化无关。

Pro-tip,也是其他人建议的:永远不要在程序中的查询中使用SELECT * 除非你有充分的理由这样做。 “我不想写出我需要的列名称”并不是一个好理由。始终枚举所需的列。当您需要的数据列列表可用时,MySQL和其他数据库系统通常可以以令人惊讶的方式优化事物。

您的查询包含此选择标准。

AND DATE(initiated) = 'dateFromYourPHPcode'

请注意,此搜索条件采用

形式
FUNCTION(column) = value

这种搜索形式无法使用该列上的任何索引。您的initiated列的数据类型为TIMESTAMP。试试这个:

 AND initiated >= 'dateFromYourPHPcode'
 AND initiated <  'dateFromYourPHPcode' + INTERVAL 1 DAY

这将在特定日期找到所有initiated项。并且,因为它不对列值使用函数,所以它可以使用索引范围扫描来执行此操作,这表现良好。如果没有索引,它可能会或可能不会有所帮助。值得一试。

我怀疑这个特定搜索的理想索引是由

创建的
 ALTER TABLE call_history 
   ADD INDEX flowExtInit (flow, extension_number, initiated)

如果您的查询需要良好的性能,您应该要求数据库的管理员添加此索引。

答案 2 :(得分:0)

您应该为表添加索引。这样MySql将获得更快的速度。我没有测试,但命令应该是这样的:

ALTER TABLE `call_history ` ADD INDEX `callhistory` (`extension_number`,`flow`,`extension_number`,`DATE(initiated)`);