8

我有 2200 万条记录的大桌子。我想执行下一个查询:

select auto_alerts from alerts_stat  where endDate > "2012-12-01"

为了提高性能,我为 endData 字段添加了 BTREE 索引:

CREATE INDEX endDate_index USING BTREE ON alerts_stat(endDate)

在我开始分析查询执行计划之后:

当我想获取 15 到 7 天前的参数时:

explain select alerts_sp from alerts_stat 
where endDate between CURDATE() - 15 and CURDATE() - 7;

我得到了下一个执行计划来处理 2,762,088 行。

'1', 'SIMPLE', 'browser_plugin_alerts_stat', 'range', 'endDate_index', 'endDate_index', '4', NULL, '2762088', 'Using where'

当我将间隔增加一天时,我收到:

explain select alerts_sp from alerts_stat 
where endDate between CURDATE() - 15 and CURDATE() - 6;

EXPLAIN 表示 MySQL 计划处理所有 22,923,126 行。

'1', 'SIMPLE', 'browser_plugin_alerts_stat', 'ALL', 'endDate_index', NULL, NULL, NULL, '22932390', 'Using where'

例如在 WHERE 进程 22,925,642 中选择不带任何条件。

我可以改进执行计划吗?也许我在某个地方有错误,或者是正常的 MySQL 行为?

4

1 回答 1

3

当结果集超过所有行的 8-9% 时,MySQL 会进行全表扫描。对我来说,看起来有一天你会在全表扫描方向添加摆动 MySQL。您可以尝试强制索引以查看结果是否更好。

更新:

根据我的阅读,MySQL 查询优化器在这样的边缘情况下往往会选择错误,因此它可以很容易地更好地强制索引。否则,这是一个简单的查询,我没有太多的优化空间。

也许在这两列上创建覆盖索引并强制使用它可能会产生最佳结果。

于 2012-12-21T13:29:22.917 回答