【发布时间】:2011-03-07 02:13:24
【问题描述】:
如何加快这个 mysql 查询的速度?
SET @rank = 0;
UPDATE dbTable
SET rank_fd = @rank := @rank + 1
ORDER BY fd2 DESC, fd3 DESC;
此查询更新约 300,000 个表行。它只是花费了太长时间......简单的控制面板(涡轮面板?)说mysqld只使用8-9%的cpu。我知道这总是正确的,但是这个查询在我的 Core i7 机器上花费的时间几乎没有。我认为在我的 P4 专用服务器上大约需要 5-10 分钟......这不会是一个问题,除非我必须为不同的值多次执行此操作。它还使其他 mysql 操作极其缓慢(几乎挂起),从而严重影响网站性能。
软件:
- CentOS 5.4 版(最终版),
- 简单控制面板版本 1.4.8,
- PHP 5.2.16
- MySQL 客户端版本:5.1.52
硬件:
- 英特尔奔腾 4 CPU 3.0GHz
- 2GB 内存
更多信息(添加于 2011 年 3 月 6 日 @ 10:06PM CST):
//Core i7 920 @ 2.6GHz, 6GB Ram
UPDATE dbTable SET rank_fd =999999999;
#275037 row(s) affected. ( Query took 7.0708 sec )
SET @rank =0;
#Your SQL query has been executed successfully ( Query took 0.0003 sec )
UPDATE dbTable SET rank_fd = @rank := @rank +1 ORDER BY fd2 DESC, fd3 DESC ;
#275037 row(s) affected. ( Query took 9.9931 sec )
//P4 3.0GHz, 2GB Ram
UPDATE dbTable SET rank_fd =999999999;
#Affected rows: 291468 (Query took 8.2165 sec)
SET @rank =0;
#Your SQL query has been executed successfully (Query took 0.0002 sec)
UPDATE dbTable SET rank_fd = @rank := @rank +1 ORDER BY fd2 DESC, fd3 DESC ;
#Affected rows: 291469 (Query took 305.2104 sec)
更多信息(添加于 2011 年 3 月 7 日 @ 下午 6:37 CST):
我有一些新信息。如果我在 P4 上做一个 select 语句:
SET @rank =0;
SELECT @rank := @rank +1 AS rank_fd FROM dbTable ORDER BY fd2 DESC, fd3 DESC LIMIT 0, 300000;
#Showing rows 0 - 29 (292,437 total, Query took 3.0448 sec)
计算一切只需要 3 秒。 no-calc 批量更新语句只需要 8 秒。什么是所有额外的工作导致它在我原来的陈述中超过 300 秒。有没有办法在不涉及 PHP 的 select calc 语句之后捕获更新。我之所以这么说,是因为如果我在 PHP 中循环它,它会比原来的语句花费更长的时间。
感谢到目前为止的所有帮助!!!
【问题讨论】:
-
这种查询速度很慢。将整个表转储到外部应用程序,在那里更新,在 db 上截断并将其从外部应用程序插入到 db 可能会更快。你需要 rank_fd 做什么?
-
@PiZzL3 :您忽略了重要信息:即磁盘 I/O 子系统....
-
是的,这种查询可能会受到 I/O 限制。
-
我相信硬盘只是普通的7200rpm,你可以在任何商店买到,没什么特别的,没有raid配置。如果我可以以某种方式为您运行基准测试,请告诉我如何。我对服务器管理了解不多。
-
@Michas:rank_fd 是由 ORDER BY 子句确定的排名(排行榜位置)。我缓存了这个,因为每次玩家统计数据发生变化时更新成本太高。