2010-01-08 46 views
3

我有一列,我想按排序,定期更新排名(每日)。我目前在代碼中使用它在MySQL中緩存行列?

get all rows from table order by column 

rank = 1 
foreach row in table 
    update row's rank to rank 
    rank++ 

這需要MySQL中每一行的更新。有更有效的方法來做到這一點嗎?

回答

4

使用的更新與聯接:

set @rank := 0; 

update tbl a join 
    (select id, @rank := @rank + 1 as new_rank from tbl order by col) b 
    on a.id = b.id set a.rank = b.new_rank; 

如果期待有很多行,你會做的加入對被索引的表,如獲得最佳性能

set @rank := 0; 

create temporary table tmp (id int primary key, rank int) 
    select id, @rank := @rank + 1 as rank from tbl order by col; 

update tbl join tmp on tbl.id = tmp.id set tbl.rank = tmp.rank; 

最後,你可能使它更快通過完全跳過更新步驟,並在新表交換(並不總是可行的):

set @rank := 0; 

create table new_tbl (id int primary key, rank int, col char(10), 
    col2 char(20)) select id, @rank := @rank + 1 as rank, col, col2 
    from tbl order by col; 

drop table tbl; 
rename table new_tbl to tbl; 
+0

謝謝,upvoted你。任何想法這種複雜性是什麼?假設所有明顯的優化(密鑰等)都被採用了? – Timmy 2010-01-08 21:56:26

+0

是的最好的表現是有一個索引時,理論上它應該是相當線性的,因爲主鍵是一個散列,並且您將更新表中的所有項目 – jspcal 2010-01-08 22:47:34

+0

可能n log n是可以的,只要它沒有'進入二次區域。我已經做了一些測試,即使對於小的N值也要快得多。只有問題可能是表鎖,我應該研究它(或者可能將它解除規範化爲自己的表)。 – Timmy 2010-01-08 22:56:24