MySQL Insert Query случайно занимает много времени - PullRequest
2 голосов
/ 05 июня 2010

Я использую MySQL для управления данными сеанса для моего приложения PHP. При тестировании приложения оно обычно очень быстрое и отзывчивое. Однако, по-видимому, случайным образом ответ будет остановлен, прежде чем наконец завершится через несколько секунд. Я сузил проблему до запроса записи сеанса, который выглядит примерно так:

INSERT INTO Session VALUES('lvg0p9peb1vd55tue9nvh460a7', '1275704013', '') ON DUPLICATE KEY UPDATE sessAccess='1275704013',sessData='';

Журнал медленных запросов содержит эту информацию:

Query_time: 0.524446  Lock_time: 0.000046 Rows_sent: 0  Rows_examined: 0

Это происходит примерно 1 из каждых 10 раз. Запрос обычно занимает ~ 0,0044 сек.

Таблица InnoDB с 60 строками. sessId - это первичный ключ с индексом BTREE.

Так как к этому обращаются при каждом просмотре страницы, это явно не приемлемое время выполнения. Почему это происходит?

Обновление: Схема таблицы: sessId: varchar (32), sessAccess: int (10), sessData: text

Ответы [ 3 ]

2 голосов
/ 06 июня 2010

Воспроизведите проблему на чем-то, что не является виртуальной машиной, тогда вы можете пожаловаться.

Виртуальные машины, особенно те, которые предоставлены произвольным третьим сторонам, имеют поведение, на которое нельзя полагаться, по моему опыту.

По всей вероятности, innoDB пытается выполнить fdatasync (). Для этого необходимо выполнить какой-то реальный физический ввод-вывод, который блокируется другой задачей на хост-компьютере (возможно, другой виртуальной машиной), выполняющей что-то. Если вы не контролируете их, вы не можете предсказать, каково будет их поведение.

Если таблица сеансов не нуждается в постоянстве при выключениях базы данных, рассмотрите ENGINE = Memory.

Если у вас нет строгих требований к долговечности данных, уменьшите параметры стойкости innodb (но это повлияет на весь сервер, а не только на таблицу)

2 голосов
/ 05 июня 2010

Обратите внимание, что для вставки в середину индекса BTree требуется довольно частое освобождение страницы и перестройка части индекса. Для кластеризованного индекса (ваш первичный ключ, вероятно, является вашим кластеризованным индексом), фактические данные строки также должны быть перемещены при перестроении страницы.

Если данные строки большие, это займет некоторое время.

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

0 голосов
/ 06 июня 2010

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

Решением было переключить движок стола на MyISAM, который ускоряет вставки.

...