我对队列系统有以下查询。困扰我的最慢的问题是这一个:
UPDATE workers SET work = $workid, last_used = NOW()
WHERE status = 1 AND work IS NULL ORDER BY last_used ASC LIMIT 1
当没有加载时,查询在大约0.04
秒内执行,但是当许多php脚本执行此查询时,执行时间越来越高,达到40.0
秒,这是一个大问题。 / p>
该表包含大约40.000
个条目,并且有status
和liking_media
的索引。查询的EXPLAIN显示解析器正在使用与status
和liking_media
的交叉,并使用3000
处理约ORDER_BY
行。 EXPLAIN
进一步显示using where; using filesort
。
它背后的VPS有8核@ 2.5ghz,12GB RAM。当查询运行速度很慢时,CPU使用率很低。当负载开始增加时,CPU使用率会高得多。
当许多php脚本运行时,如何在加载时大大提高此查询的性能?我可以调整一般的mysql设置来修复它吗?或者表架构是坏的还是缺少索引?我希望能够在不失去性能的情况下每秒运行大约300个查询。
答案 0 :(得分:2)
查询的问题是找到要更新的相应行。对于此查询:
UPDATE workers
SET work = $workid, last_used = NOW()
WHERE status = 1 AND work IS NULL
ORDER BY last_used ASC
LIMIT 1;
您需要以下综合索引:workers(status, work, last_used)
。
这可以加快查询速度并防止多个更新互相锁定。
答案 1 :(得分:2)
我认为这应该避免使用ORDER BY,这会强制查询获取所有结果,而不仅仅是最新last_used
的结果:
UPDATE workers
INNER JOIN (
SELECT MIN(last_used), worker_id
FROM workers
) AS newest_worker
ON newest_workder.worker_id = workers.worker_id
SET workers.work = $workid, workers.last_used = NOW()
WHERE workers.status = 1 AND workers.work IS NULL