mik*_*e14 5 mysql performance optimization
我的服务器上有一个简单的 PHP 发送电子邮件脚本的问题,该脚本通过 cronjob 每分钟运行一次。该脚本包含一个在大多数情况下运行速度非常快的 MySQL 查询,但随机将“永远”运行。
感觉就像一个类似的问题:https : //stackoverflow.com/questions/976739/mysql-query-randomly-takes-forever
在运行 MySQL 查询时,在看似随机的时间里,我的服务器上的负载从平均 0.5 激增到 8,我的整个服务器慢慢地接近停止。查询最终会完成,但有时会运行超过 10 分钟——在“正常”情况下,查询会在 0.2 秒内完成。
这是查询:
SELECT * FROM email_messages
WHERE time_created <= "2013-04-22 10:40:00" AND is_sent = 0 AND is_cancelled = 0
LIMIT 6
Run Code Online (Sandbox Code Playgroud)
time_created 是(应该)索引 - 其目的是在发送前创建一个 10 分钟的延迟,以便在必要时取消电子邮件。
我已将其与此查询隔离,因为当此 cronjob 关闭时,我的服务器运行良好,而没有平均负载峰值。
我的服务器是具有 2GB RAM 的 VPS。数据库并不大(总共 750mb),但选择的 email_messages 表是迄今为止最大的,大约 400mb。
经过研究,我认为是MySQL查询缓存问题,因为打开了查询缓存。但是关闭查询缓存并没有解决问题。
我通过设置关闭了 query_cache query_cache_size = 0。
关于这里可能发生什么的任何想法?
[结论]
我做了一个实验,通过使用我的主键在查询中包含一个条件,以便只搜索最后 1000 个表条目。
... AND id > 131000 ...
Run Code Online (Sandbox Code Playgroud)
在这种情况下运行 cronjob 解决了这个问题,在 mysql 控制台中进一步调查EXPLAIN发现索引time_created 没有按照我的预期创建。
我现在需要阅读如何使用HeidiSQL正确创建索引,因为 HeidiSQL 告诉我有一个索引键,time_created但EXPLAIN另有说明。这可能是年轻球员的陷阱!
为了加快查询的执行速度,您需要创建复合索引:
ALTER TABLE email_messages
ADD INDEX idx1(is_sent, is_cancelled, time_created);
Run Code Online (Sandbox Code Playgroud)
详细信息:多列索引
| 归档时间: |
|
| 查看次数: |
3030 次 |
| 最近记录: |