0

我正在对具有数千行的表运行查询:

$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'

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

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

4

3 回答 3

1

under 子句的顺序WHERE与优化无关。

专业提示,其他人也建议: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)

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

于 2013-09-30T11:38:50.493 回答
1

以下是一些建议:

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

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

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

4)一次获取所有数据。

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

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

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

于 2013-09-30T11:12:41.630 回答
0

您应该将索引添加到您的表中。这样 MySql 会更快地获取。我没有测试,但命令应该是这样的:

ALTER TABLE `call_history ` ADD INDEX `callhistory` (`extension_number`,`flow`,`extension_number`,`DATE(initiated)`);
于 2013-09-30T11:13:55.603 回答