[英]Help speeding up MySql Query
我將如何加快此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操作極其緩慢(幾乎掛起),從而極大地影響網站性能。
軟件:
硬件:
更多信息(於2011年3月6日@ CST下午10:06發布):
//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日@ CST下午6:37):
我有一些新信息。 如果我在P4上執行選擇語句:
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中循環執行此操作,則它會比原始語句花費更長的時間。
謝謝到目前為止的所有幫助!!!
您正在修改表中的每一行,這當然會很慢。 根據rank_fd
的使用方式,您可能只需在fd2
和fd3
上放置索引並在運行時計算等級就可以fd2
fd3
。
您可以使用存儲過程和臨時表來加快排名過程。
以下示例使用一個擁有150萬行的玩家得分表,並在3個回合(500K * 3)中獲得500K玩家得分,並在大約1輪內更新第1輪(500K行)的排名。 5秒。
希望這可以幫助 :)
示例表和存儲過程
drop table if exists player_scores;
create table player_scores
(
round_id smallint unsigned not null,
player_id int unsigned not null,
score_1 int unsigned not null default 0,
score_2 int unsigned not null default 0,
rank int unsigned not null default 0,
primary key (round_id, player_id)
)
engine=myisam;
drop procedure if exists update_player_score_ranking;
delimiter #
create procedure update_player_score_ranking
(
p_round_id smallint unsigned
)
begin
create table tmp_player_scores engine=memory select
round_id, player_id, score_1, score_2, @rank:= @rank + 1 as rank
from
player_scores
inner join (select @rank:=0) r
where
round_id = p_round_id
order by
score_1 desc, score_2 desc;
delete from player_scores where round_id = p_round_id;
insert into player_scores select * from tmp_player_scores;
drop table if exists tmp_player_scores;
end #
delimiter ;
檢測結果:
select count(*) from player_scores;
+----------+
| count(*) |
+----------+
| 1500000 |
+----------+
1 row in set (0.00 sec)
select count(*) from player_scores where round_id = 1;
+----------+
| count(*) |
+----------+
| 500000 |
+----------+
1 row in set (0.07 sec)
select * from player_scores where round_id = 1 order by score_1 desc, score_2 desc limit 5;
+----------+-----------+---------+---------+------+
| round_id | player_id | score_1 | score_2 | rank |
+----------+-----------+---------+---------+------+
| 1 | 456937 | 65534 | 49579 | 0 |
| 1 | 72439 | 65534 | 44537 | 0 |
| 1 | 16427 | 65534 | 43045 | 0 |
| 1 | 259871 | 65534 | 32095 | 0 |
| 1 | 324702 | 65534 | 15227 | 0 |
+----------+-----------+---------+---------+------+
5 rows in set (0.71 sec)
call update_player_score_ranking(1);
Query OK, 0 rows affected (5.57 sec)
select * from player_scores where round_id = 1 order by rank limit 5;
+----------+-----------+---------+---------+------+
| round_id | player_id | score_1 | score_2 | rank |
+----------+-----------+---------+---------+------+
| 1 | 456937 | 65534 | 49579 | 1 |
| 1 | 72439 | 65534 | 44537 | 2 |
| 1 | 16427 | 65534 | 43045 | 3 |
| 1 | 259871 | 65534 | 32095 | 4 |
| 1 | 324702 | 65534 | 15227 | 5 |
+----------+-----------+---------+---------+------+
5 rows in set (1.29 sec)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.