我在一个有数千行的表上运行查询:
$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 = ...)
?
答案 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)`);