优化mysql设置/表以获得负载下的性能

时间:2014-08-31 20:09:45

标签: php mysql sql performance innodb

我对队列系统有以下查询。困扰我的最慢的问题是这一个:

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个条目,并且有statusliking_media的索引。查询的EXPLAIN显示解析器正在使用与statusliking_media的交叉,并使用3000处理约ORDER_BY行。 EXPLAIN进一步显示using where; using filesort

它背后的VPS有8核@ 2.5ghz,12GB RAM。当查询运行速度很慢时,CPU使用率很低。当负载开始增加时,CPU使用率会高得多。

当许多php脚本运行时,如何在加载时大大提高此查询的性能?我可以调整一般的mysql设置来修复它吗?或者表架构是坏的还是缺少索引?我希望能够在不失去性能的情况下每秒运行大约300个查询。

2 个答案:

答案 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