2010-01-08 2 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

Спасибо, поддержал вас. Есть идеи, что такое сложность? Предполагая все очевидные оптимизации (ключи и т. Д.)? – Timmy

+0

Да, лучшая производительность - это когда есть индекс, теоретически он должен быть довольно линейным, поскольку первичный ключ является хешем, и вы будете обновлять все элементы в таблице. – jspcal

+0

Вероятно, n log n в порядке, если это не так, t погрузиться в квадратичную территорию. Я провел некоторое тестирование, и это значительно быстрее, даже для небольших значений N. Только проблема может быть возможной блокировкой таблицы, которую я должен изучить (или, возможно, де-нормализовать ее в своей таблице). – Timmy

Смежные вопросы