MySQL - Обновление выбора с итерационными целыми числами - PullRequest
0 голосов
/ 06 января 2020

Здравствуйте еще раз rnet ботаники!

Технически Я решил эту проблему, но хочу знать, есть ли более оптимальный маршрут, по которому я должен идти ...

У меня есть большая таблица (~ 4 м строк), которая представляет собой набор данных, сегментированных с использованием int "chip". Имеется 6 сегментов данных, поэтому идентификаторы чипов с 1 по 6.

Из этих 6 сегментов мне нужно присвоить целое число order , которое должно быть итеративным, поскольку оно представляет точное расположение данных на указанном сегменте.

Мое решение (было) это:

# set iterative
set @i:=0;

# init
update table set `order` = @i:=(@i+1) where chip = 1;

Это работает . Но он настолько медленный, что иногда вызывает ошибку тайм-аута. Мне нужно запустить его 6 раз, и он может быть вызван нашим приложением при необходимости. Может быть, мне просто нужно уделить больше времени настройкам MySQL, чтобы учесть медленный запрос, или есть оптимальное, более простое решение для этого?

Спасибо за совет.

Редактировать:

Я нашел решение, которое работает точно и занимает ~ 50 секунд.

Я сейчас использую заказанный оператор select, связанный в обновлении, использует сгенерированную таблицу соединений, которая повторяется в столбце.

См .:

set @count:= 0;
update 
table as target,
    (select 
    (@count :=  @count+1) as row_num,
    t.*
    from table as t
    where chip = 1
    order by t.id asc) as table_with_iterative
set target.`order` = table_with_iterative.row_num
where target.id = table_with_iterative.id; 

Ответы [ 2 ]

0 голосов
/ 06 января 2020

Я нашел решение, которое работает точно и занимает ~ 50 секунд.

Это обрабатывает обновления, вышедшие из строя.

Теперь я использую упорядоченный оператор выбора, соединенный в операторе обновления, с использованием сгенерированной таблицы соединений, которая повторяется в столбце row_num.

См .:

set @count:= 0;
update 
table as target,
    (select 
    (@count :=  @count+1) as row_num,
    t.*
    from table as t
    where chip = 1
    order by t.id asc) as table_with_iterative
set target.`order` = table_with_iterative.row_num
where target.id = table_with_iterative.id; 
0 голосов
/ 06 января 2020

Я думаю, что, если возможно, вы должны назначить порядковые номера, когда вы вставляете строки в таблицу в первый раз. Строго говоря, база данных SQL не обещает, что строки будут изначально появляться внутри таблицы в порядке операторов INSERT.

Одна из возможных возможностей, которую мне приходит в голову, - это использовать поле с автоинкрементом. в этой таблице, потому что это будет express порядок, в котором были добавлены строки. Но значения полей для любого данного chip, хотя и возрастающие, могут не быть последовательными и, несомненно, не начнутся с 1.

Если вам действительно нужно такое поле, я думаю, что я определю отдельное поле (значение по умолчанию: NULL) для его хранения. Затем очень простая хранимая процедура может запросить строки для заданного чипа (ORDER BY номер автоинкремента) и назначить последовательный порядковый номер на основе 1 этому отдельному полю. (Несколько более сложный запрос мог бы идентифицировать все списки, у которых пока нет этих номеров, и пронумеровать их все сразу.)

...