2010-01-08 7 views
3

J'ai une colonne que je veux trier, avec des mises à jour périodiques sur le rang (quotidien). Je l'utilise actuellement dans le codeLa ligne de mise en cache se classe dans MySQL?

get all rows from table order by column 

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

cela prend une mise à jour pour chaque ligne dans MySQL. Existe-t-il des moyens plus efficaces de le faire?

Répondre

4

Utilisez une mise à jour avec une jointure:

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; 

Si attendant d'avoir beaucoup de lignes, vous obtiendrez les meilleures performances en faisant la jointure sur une table qui est indexé, par exemple:

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; 

Enfin, vous pourriez potentiellement faire plus rapidement en sautant l'étape de mise à jour entièrement et échange dans une nouvelle table (pas toujours possible):

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

Merci, vous a augmenté. Une idée de ce qu'est cette complexité? En supposant que toutes les optimisations évidentes (clés, etc) sont prises? – Timmy

+0

ouais la meilleure performance est quand il y a un index, théoriquement il devrait alors être plutôt linéaire puisque la clé primaire est un hachage, et vous mettriez à jour tous les éléments dans le tableau – jspcal

+0

Probablement n log n est correct, tant qu'il doesn ' t plonger dans le territoire quadratique. J'ai fait quelques tests et c'est beaucoup plus rapide, même pour les petites valeurs de N. Seul le problème pourrait être le verrouillage de table, que je devrais examiner (ou peut-être dé-normaliser à sa propre table). – Timmy