Как оптимизировать update в mysql?

Имеется таблица:
CREATE TABLE test.sites_list (
  id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  url varchar(255) NOT NULL COMMENT 'Домен',
  reg varchar(100) DEFAULT NULL COMMENT 'Регистратор',
  domain_created date DEFAULT NULL COMMENT 'Дата регистрации домена',
  last_http_code int(11) NOT NULL COMMENT 'Последний статус ответа сервера',
  created_at timestamp DEFAULT CURRENT_TIMESTAMP COMMENT 'Время создания',
  updated_at timestamp DEFAULT '0000-00-00 00:00:00',
  status int(11) NOT NULL COMMENT 'Статус',
  marker varchar(255) NOT NULL DEFAULT '',
  proc varchar(255) DEFAULT NULL,
  PRIMARY KEY (id),
  INDEX domainCreated_updatedAt (domain_created, updated_at),
  INDEX Status_Proc_dCreated (status, proc, domain_created, updated_at),
  INDEX UpdatedAt_Status (updated_at, status)
)
ENGINE = INNODB
AUTO_INCREMENT = 19795014
AVG_ROW_LENGTH = 447
CHARACTER SET utf8
COLLATE utf8_general_ci;


Имеется запрос:
UPDATE `sites_list` SET `proc` = '2cc16b53f60654d97bcfb265eb0082a4'  WHERE `status` = 0 AND `proc` = '' ORDER BY `domain_created` DESC, `updated_at` LIMIT 50;


Ситуация:
В таблице, больше 3 млн. записей.
Этот запрос выполняется несколько минут.
Запрос SHOW PROFILE показывает, что все время уходит на init.

Как можно оптимизировать UPDATE или найти компромисс?
  • Вопрос задан
  • 3487 просмотров
Пригласить эксперта
Ответы на вопрос 6
fornit1917
@fornit1917
Составной индекс по proc и status имеется?
Ответ написан
Комментировать
serovvitaly
@serovvitaly Автор вопроса
INDEX Status_Proc_dCreated (status, proc, domain_created, updated_at),
Ответ написан
serovvitaly
@serovvitaly Автор вопроса
Вот все индексы:
INDEX domainCreated_updatedAt (domain_created, updated_at),
INDEX Status_Proc_dCreated (status, proc, domain_created, updated_at),
INDEX UpdatedAt_Status (updated_at, status)

status, proc можно взять из второго, а domain_created, updated_at - из первого, хотя EXPLAIN SELECT показывает только Status_Proc_dCreated
Ответ написан
Комментировать
Карты говорят, что дело может быть в разном порядке сортировки в ORDER BY. Попробуйте ORDER BY `domain_created` DESC, `updated_at` DESC , если логика приложения позволяет.

А вообще хорошо бы увидеть
EXPLAIN SELECT * FROM `sites_list`
WHERE `status` = 0 AND `proc` = '' 
ORDER BY `domain_created` DESC, `updated_at` LIMIT 50
Ответ написан
serovvitaly
@serovvitaly Автор вопроса
EXPLAIN SELECT * FROM `sites_list`
WHERE `status` = 0 AND `proc` = '' 
ORDER BY `domain_created` DESC, `updated_at` LIMIT 50

Результат:
674a2630360f90cd1a154dcc0bb266dbf570a119
Ответ написан
Комментировать
golotyuk
@golotyuk
Попробуйте также посмотреть на профиль запроса с помощью SHOW PROFILE.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы