2013-05-02 58 views
0

我通过DESC在300k行的表上选择INT行,然后选择@rownum:= @ rownum + 1更新同一行的RANK字段。有没有办法减慢MySQL查询以降低CPU使用率?

它工作完美,但需要很长时间。我可以接受更长的时间,但是我是否可以稍微让它睡一会儿,给CPU一些空闲空间来完成其他工作?

就像把睡眠(0.25秒)在一段时间(1> 0)...循环

UPDATE: SET @ ROWNUM = 0; 更新用户u,(SELECT @rownum:= @ rownum + 1作为等级,id FROM用户u按等级DESC排序)作为bb SET u.rank = bb.rank WHERE u.id = bb.id

+0

这听起来很不妥。这听起来像你的方法来查询可能是一个问题,因为如果使用适当的索引,更新到300K行不应该花那么长时间。你可以在你的查询中添加信息吗? – 2013-05-02 16:47:17

+0

我已将我的查询添加到问题 – frankish 2013-05-02 16:49:05

+0

“score”列中是否有索引?对于这个查询,“explain”是什么意思?如果MySQL执行这样的查询作为笛卡尔产品,我不会感到惊讶,但是这不是一个无论如何都应该做的操作。 – 2013-05-02 16:52:41

回答

0

否。您可以通过将low_priority添加到更新中,或者通过将high_priority添加到选择中来对insert delayed声明的优先级产生一些较小的影响。这只会影响一些使用它们的存储引擎中的表锁定队列。然而,你不能有比这更精细的控制。它也不应该是这样,因为DBMS将在内部进行自我平衡,并且一个慢速查询不应该使另一个查询更慢。如果通过“其他工作”,您的意思是在同一台服务器上执行其他任务,则可以仅使用ionicenice整个mysqld进程。

回答了实际问题后,您的查询可能会很慢,因为它会错过您正在排序的字段上的索引,因此会在执行计划上触发filesorttemporary标志。解决这个问题可能会让整个问题变得毫无意义。

+0

尽管我得到了,我不能得到一个YES的答案,这是推荐ionice/nice最接近的答案。 – frankish 2013-05-02 17:25:11

1

我可能会创建一个临时表与自动增量ID来做到这一点。然后您可以将排序后的值输入到临时表中以生成排序序列。然后,您可以通过连接更新原始表。

+0

谢谢,虽然这没有奏效(我在你的答案后试过了),我会创建一个名为user_rank的永久表和TRUNCATE,INSERT,我将查询该表而不是“从用户中选择级别”。这几乎立即返回。 – frankish 2013-05-02 17:26:33

+0

是的,如果你想拥有永久性的桌子,那也可以。不知道为什么临时表不会为你工作,虽然 – 2013-05-02 17:30:14

+0

我必须查询“等级”值“任何”的时间。这需要永久表或从temptable到主用户表的大量更新(这会长时间锁定用户表) – frankish 2013-05-02 17:58:41