【发布时间】:2014-08-31 20:09:44
【问题描述】:
我对队列系统有以下查询。困扰我的最慢的查询是这个:
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 秒,这是一个大问题。
该表有大约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 个此类查询。
【问题讨论】:
-
听起来好像有别的东西在锁表。可能其他查询需要优化
-
在一个while循环中依次执行5个查询以获得作业。我已经记录了所有这些的执行时间,它总是只显示我在这里发布的查询的长执行时间,其他的保持很快。只有这 5 个查询会经常执行,因此速度变慢的查询必须在这 5 个查询范围内。由于我发布的查询总是很慢,我怀疑这是问题所在,有意义吗?
-
workers 表是否有唯一的 id 字段?这将有助于使用子查询摆脱 ORDER BY。
-
它有一个 worker_id 作为主要但 last_used 的事情是我总是希望首先获得最少使用的工人。该查询更新了一个worker条目并将其设置为last_used = NOW(),因此当多次发出查询时不会返回同一个worker,除非它再次成为最少使用的一个。
标签: php mysql sql performance innodb