В настоящее время запрос NOT IN
затрагивает все 100 000 строк. Давайте избежим этого, изменив запрос и схему. Вместо того, чтобы устанавливать is_online
для всех пользователей, давайте разработаем способ, позволяющий вам касаться только тех, которые в настоящее время онлайн.
Вместо того, чтобы is_online
был логическим значением, давайте сделайте это или DATETIME
или BIGINT
. Затем установите новое, более высокое значение для тех, кто в сети, игнорируя остальные.
Для этого потребуется еще один бит информации - новое высокое значение. Просто сохраните его в другой таблице с одной строкой с одним столбцом.
Эта схема позволяет избежать использования меток времени в комментариях. Единственные пользователи, которые «онлайн», - это пользователи с последним значением в is_online
; все остальные находятся в автономном режиме.
Теперь давайте проверим остальную часть схемы. Вы действительно нуждаетесь в id
и username
? Бросить id
и сделать username
PRIMARY KEY
; это ускорит процесс, потому что не нужно будет выполнять двойной поиск - сначала для поиска идентификатора с учетом имени пользователя, затем для получения строки UPDATE
. (Предупреждение: могут быть проблемы, если это FOREIGN KEY
из другой таблицы. Если это так, пожалуйста, предоставьте более подробную информацию.)
Другой совет - Использование 1000 операторов для прикосновения к 1000 строкам намного медленнее, чем использование один запрос. Чтобы сделать несколько обновлений различных значений, используйте IODKU.
Я надеюсь, что все это будет сводиться к 3 sql утверждениям:
BEGIN;
$hv = SELECT high_value FROM HighValue FOR UPDATE;
$hv++;
INSERT INTO MainTable
VALUES
('user1', 'blah1', $hv),
('user2', 'blah2', $hv),
...
ON DUPLICATE KEY UPDATE
data = VALUES(data), -- sets the new `data` value
is_online = $hv ;
UPDATE HighValue SET high_value = $hv;
COMMIT;