Медленные обновления с MySQL innoDB (невежественный) - PullRequest
0 голосов
/ 27 января 2012

У меня довольно простой запрос, который выполняется очень быстро в большинстве случаев времени и в других редких случаях занимает до 30 секунд. Я понятия не имею, что вызывает это. Вот пример того, о чем я говорю.

mysql> ОБНОВЛЕНИЕ matchSessionMembers msm ПРИСОЕДИНЯЙТЕСЬ к matchSessions ms ON msm.matchNo = ms.matchNo AND ms.STATUS! = 'N' SET msm.STATUS = 'P' ГДЕ msm.memberNo = 7 И msm.STATUS = 'M';
Запрос в порядке, затронуто 0 строк (0,00 с)
Количество подходящих строк: 0 Изменено: 0 Предупреждений: 0

mysql> ОБНОВЛЕНИЕ matchSessionMembers msm ПРИСОЕДИНЯЙТЕСЬ к matchSessions ms ON msm.matchNo = ms.matchNo AND ms.STATUS! = 'N' SET msm.STATUS = 'P' ГДЕ msm.memberNo = 7 И msm.STATUS = 'M';
Запрос в порядке, затронуто 0 строк (0,00 с)
Строк соответствует: 0 Изменено: 0 Предупреждений: 0

mysql> ОБНОВЛЕНИЕ matchSessionMembers msm СОЕДИНЕНИЕ matchSessions ms ON msm.matchNo = ms.matchNo AND ms.STATUS! = 'N' SET msm.STATUS = 'P' ГДЕ msm.memberNo = 7 И msm.STATUS = 'M';
Запрос в порядке, затронуто 0 строк (3,01 с)
Строк соответствует: 0 Изменено: 0 Предупреждений: 0

mysql> ОБНОВЛЕНИЕ matchSessionMembers msm ПРИСОЕДИНЯЙТЕСЬ к matchSessions ms ON msm.matchNo = ms.matchNo AND ms.STATUS! = 'N' SET msm.STATUS = 'P' ГДЕ msm.memberNo = 7 И msm.STATUS = 'M';
Запрос в порядке, затронуто 0 строк (0,00 с)
Количество подходящих строк: 0 Изменено: 0 Предупреждений: 0

mysql> ОБНОВЛЕНИЕ matchSessionMembers msm СОЕДИНЕНИЕ matchSessions ms ON msm.matchNo = ms.matchNo AND ms.STATUS! = 'N' SET msm.STATUS = 'P' ГДЕ msm.memberNo = 7 И msm.STATUS = 'M';
Запрос в порядке, затронуто 0 строк (1,88 с)
Соответствующие строки: 0 Изменено: 0 Предупреждения: 0

mysql> ОБНОВЛЕНИЕ matchSessionMembers msm ПРИСОЕДИНЯЙТЕСЬ к matchSessions ms ON msm.matchNo = ms.matchNo AND ms.STATUS! = 'N' SET msm.STATUS = 'P' ГДЕ msm.memberNo = 7 И msm.STATUS = 'M';
Запрос в порядке, затронуто 0 строк (0,00 с)
Строк соответствует: 0 Изменено: 0 Предупреждений: 0

В этом запросе я установил индексы для всех msm.matchNo, ms.matchNo, ms.status, msm.status и msm.memberNo.

Я выполнял один и тот же запрос 6 раз, и в 4 случаях запросы выполнялись менее чем за секунду, в то время как 2 случая занимали более секунды для обработки. Я провел еще одно тестирование и получил данные профиля для одного из наиболее серьезных случаев, для выполнения которого потребовалось до 30 секунд.

mysql> SHOW PROFILE FOR QUERY 3;  
+---------------------------+-----------+  
| Status                    | Duration  |  
+---------------------------+-----------+  
| starting                  |  0.000075 |  
| checking permissions      |  0.000013 |  
| checking permissions      |  0.000012 |  
| Opening tables            |  0.000073 |  
| checking permissions      |  0.000011 |  
| checking permissions      |  0.000013 |  
| System lock               |  0.000023 |  
| init                      |  0.000021 |  
| updating main table       |  0.000014 |  
| optimizing                |  0.000020 |  
| statistics                |  0.000117 |  
| preparing                 |  0.000028 |  
| executing                 |  0.000011 |  
| Sending data              | 31.940094 | <==
| updating reference tables |  0.000039 |  
| end                       |  0.000016 |  
| end                       |  0.000015 |  
| query end                 |  0.000048 |  
| closing tables            |  0.000039 |  
| freeing items             |  0.000036 |  
| logging slow query        |  0.000011 |  
| cleaning up               |  0.000014 |  
+---------------------------+-----------+  

У меня есть несколько других запросов ОБНОВИТЬ с похожими симптомами. Почему этот запрос выполняется так долго, хотя на самом деле не обновляются строки? Что может быть этим узким местом "Отправка данных"?

** edit: добавлен код CREATE TABLE для обеих используемых таблиц

CREATE TABLE matchSessionMembers (
matchNo int (11) NOT NULL,
memberNo int (11) NOT NULL,
status char (1) NOT NULL ПО УМОЛЧАНИЮ 'M' COMMENT 'M = совпадение, P = в ожидании, Y = сказал Да, N = сказал Нет, D = удален',
muted char (1) NOT NULL ПО УМОЛЧАНИЮ 'N',
deleted char (1) NOT NULL ПО УМОЛЧАНИЮ 'N',
regDatetime datetime DEFAULT NULL,
exitDatetime datetime DEFAULT NULL,
ПЕРВИЧНЫЙ КЛЮЧ (matchNo, memberNo),
КЛЮЧ status (status),
КЛЮЧ FK_matchSessionMembers_memberNo (memberNo),
КЛЮЧ regDatetime (regDatetime),
КЛЮЧ FK_matchSessionMembers_matchNo (matchNo),
ОГРАНИЧЕНИЕ FK_matchSessionMembers_matchNo ИНОСТРАННЫЙ КЛЮЧ (matchNo) ССЫЛКИ matchSessions (matchNo),
ОГРАНИЧЕНИЕ FK_matchSessionMembers_memberNo ИНОСТРАННЫЙ КЛЮЧ (memberNo) ССЫЛКИ members (memberNo)
) ENGINE = InnoDB CHARSET ПО УМОЛЧАНИЮ = utf8

CREATE TABLE matchSessions (
matchNo int (11) NOT NULL AUTO_INCREMENT,
memberCount int (11) NOT NULL,
status char (1) NOT NULL ПО УМОЛЧАНИЮ 'P' COMMENT 'P = ожидающий, Y = успешный, N = неудачный, X = истекший,
isQuickMatch char (1) NOT NULL ПО УМОЛЧАНИЮ 'N',
open char (1) NOT NULL ПО УМОЛЧАНИЮ 'N',
regDatetime datetime ПО УМОЛЧАНИЮ NULL,
activeDate дата ПО УМОЛЧАНИЮ НУЛЬ,
expireDate дата ПО УМОЛЧАНИЮ НУЛЬ,
ПЕРВИЧНЫЙ КЛЮЧ (matchNo),
KEY status (status),
KEY activeDate (activeDate),
KEY expireDate (expireDate)
) ENGINE = InnoDB AUTO_INCREMENT = 113912 CHARSET ПО УМОЛЧАНИЮ = utf8

1 Ответ

1 голос
/ 29 января 2012

Я понял это.

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

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

Надеюсь, это поможет всем, у кого возникли подобные проблемы.

...