【发布时间】:2020-04-26 22:14:10
【问题描述】:
我在这几天一直在尝试不同的方法来减少由于最近的 AJAX 脚本导致的 95-135% 的 CPU 负载,调用此查询:
SELECT COUNT(*) as total FROM users WHERE last_access >= DATE_SUB(NOW(), INTERVAL 1 MINUTE) ORDER BY last_access DESC LIMIT 16
我已经尝试COUNT(id) 来减少表扫描时间,我添加了LIMIT 和ORDER BY,我认为它有所改善,但我不知道。我在我的 BSD 机器上监控 top -P,CPU 一直在飙升,几乎要杀死 apache,同时依靠它来进行查询测试。
我们有一个查询 AJAX 脚本的 jquery 位,并根据在 jquery 端以 15 秒的间隔(查询语句为 1 分钟)根据最后在线用户返回表计数。一天还好,然后注意到服务器超时运行,粉丝们陷入了混乱。
我们最终删除了 MySQL 5.7 并安装了 MariaDB 12.4 - 这带来了巨大的变化,但是当它的负载降低了 ~20% CPU 时,它也在挣扎......所以查询是坏的。我禁用了脚本,果然,CPU 平均下降到 15-30%,但这是我们网站用户体验的重要组成部分。例如,这只是报告(455 个在线),并每 15 秒(动态)更新文本。
我的问题是.. 由于 9600 条记录 表上的 SELECT(*) 语句有 15 秒的间隔命中,我该如何优化它以使 SQL 服务器不会崩溃和糟糕用完所有可用内存?
我没有包含脚本,因为它运行良好,查询是问题,但会在需要时提供。
这是我们网站上唯一的 AJAX 脚本。没有进行其他 AJAX 调用。
亲切的问候,
【问题讨论】:
-
你试过
SELECT COUNT(TBLPRIMARYKEY) AS TOTAL FROM USERS WHERE last_access >= DATE_SUB(NOW(), INTERVAL 1 MINUTE) ORDER BY last_access DESC LIMIT 16吗? -
我的意思是你只需要用户表中有多少条符合这种条件的记录,不需要包含所有列,只需表主键即可。
-
主键是 ID,我尝试了 SELECT(id) 并发现差别不大,我认为这也是解决方案,也许在另一种事务情况下。
-
请发布 A) SHOW CREATE TABLE users 的 TEXT 结果;所以我们可以看到结构和索引 B) EXPLAIN (你的查询);
标签: php jquery mysql ajax performance