Медленный запрос MySQL, даже если используется первичный индекс и хороший план EXPLAIN

У меня есть таблица с высокой посещаемостью и 1,3 млн строк, в которой наблюдается поток медленных запросов следующего типа:

UPDATE app_info SET data1=269223, data2=0, data3=164, last_update='2012-08-30'
WHERE slice_id=7636 AND app_id=375 AND user_id=21012286 AND mode_id=1;

Тем не менее, план объяснения для этого запроса указывает оптимальный план (мы используем первичный ключ):

explain select * from app_info
where slice_id=7636 and app_id=375 and user_id=21012286 and mode_id=1\G

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: app_info
         type: const
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 18
          ref: const,const,const,const
         rows: 1
        Extra: 

Вот журнал медленных запросов:

 Time: 120830  3:23:37
# User@Host: rest_service[rest_service] @ app01.peak.mindjolt.com [10.0.0.174]
# Thread_id: 10091395  Schema: platform  Last_errno: 0  Killed: 0
# Query_time: 68.559347  Lock_time: 0.000045  Rows_sent: 0  Rows_examined: 1 Rows_affected: 1  Rows_read: 2
# Bytes_sent: 52  Tmp_tables: 0  Tmp_disk_tables: 0  Tmp_table_sizes: 0
# InnoDB_trx_id: 575CBF3B9
UPDATE app_info SET data1=269223, data2=0, data3=164, last_update='2012-08-30' WHERE slice_id=7636 AND app_id=375 AND user_id=21012286 AND mode_id=1;

Около 30% всех запросов занимают> 1 с, и около 10% всех запросов занимают> 10 с (!)

Что может быть причиной медленного выполнения этого запроса? Насколько я могу судить, план идеален, была просканирована только одна строка и не было потрачено время на получение блокировки. Итак, что идет?

Обновление: забыл указать характеристики сервера, это 64G Quad Xeon X5650 2,66 ГГц (24 ядра), сервер Mysql 5.1.52-rel11.6-log Percona 11.6, 12-дисковый массив PERC H700 RAID. Этот сервер работал отлично в течение долгого времени (время безотказной работы указывает на 565 дней).

Обновление 2: эта таблица имеет только один индекс, который является первичным индексом, состоящим из кортежа (app_id, user_id, slice_id, mode_id). Кроме того, это мастер только для записи, три других подчиненных сервера обрабатывают все операции чтения.


person Blanka    schedule 30.08.2012    source источник
comment
EXPLAIN не работает с запросами UPDATE, насколько мне известно.   -  person Adrian Cornish    schedule 30.08.2012
comment
возможно, но разве журнал медленных запросов не показывает, что запрос на обновление сканировал только одну строку, как показывает мой план объяснения для измененного запроса на выборку?   -  person Blanka    schedule 30.08.2012


Ответы (1)


Я подозреваю, что в одном или нескольких столбцах, которые вы обновляете, есть индексы, и с таким большим индексом может потребоваться некоторое время, чтобы сбросить эти индексы и перестроить необходимые части. Я бы провел аудит индексов и удалил все, которые не дают вам очень ценного select прироста производительности. Быстрый поиск также выявил задержку опция -key-write (только для MyISAM :-/), которая может помочь. Последним рубежом (если это действительно проблема) будет изучение архитектуры master-for-write/slave-for-read, а затем выполнение значительно меньшего количества индексов на вашем главном сервере записи.

редактировать Я немного поискал параметры InnoDB и нашел это ТАК вопрос о том, как временно отключить для них ключи для операций записи.

person Chris Trahey    schedule 30.08.2012
comment
Отличный момент, не учитывал обновление индекса в уравнении. К сожалению, только что проверил таблицу, и ее единственным индексом является кортеж (app_id, user_id, slice_id, mode_id). И обновление не обновляет ни один ключевой столбец. Кстати, у нас уже есть архитектура write-master/read-slave. Это на главном, а чтение идет на три подчиненных сервера. - person Blanka; 30.08.2012