Почему этот запрос медленный? Должен ли я использовать MyISAM вместо InnoDB здесь? - PullRequest
2 голосов
/ 02 марта 2010

Я получаю примерно 5 раз в час в журналах медленных запросов:

# Query_time: 11.420629  Lock_time: 0.000033 Rows_sent: 0  Rows_examined: 0
SET timestamp=1267487708;
INSERT INTO record_lock (record_lock.module_id, record_lock.module_record_id, record_lock.site_id, record_lock.user_id, record_lock.expiration_date_time, record_lock.date_time_created) VALUES ('40', '12581', '940', '155254', '2010-03-02 00:24:57', '2010-03-01 23:54:57');

# Query_time: 2.095374  Lock_time: 0.000031 Rows_sent: 0  Rows_examined: 0
SET timestamp=1267488361;
DELETE
FROM record_lock
WHERE record_lock.user_id = 221659 AND record_lock.expiration_date_time IS NOT NULL;

Таблица record_lock в настоящее время использует InnoDB, и в ней сейчас находится менее десятка записей.

В нашей системе несколько тысяч активных пользователей. Каждый раз, когда они редактируют запись, мы вставляем в эту таблицу. И на каждой странице, загружаемой в любом месте системы, мы 1) ВЫБИРАЕМ из таблицы, чтобы увидеть, есть ли какие-либо блокировки для текущего пользователя, и 2) запускаем запрос DELETE для этой таблицы, если есть какие-либо записи для пользователя, ссылаясь первичные ключи таблицы в предложении WHERE.

Вот схема таблицы:

CREATE TABLE IF NOT EXISTS `record_lock` (
  `module_id` int(10) unsigned NOT NULL,
  `module_record_id` int(10) unsigned NOT NULL,
  `site_id` int(10) unsigned NOT NULL,
  `user_id` int(10) unsigned NOT NULL,
  `expiration_date_time` datetime NOT NULL,
  `date_time_created` datetime DEFAULT NULL,
  PRIMARY KEY (`module_id`,`module_record_id`),
  KEY `record_lock_site_id` (`site_id`),
  KEY `index_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Ответы [ 4 ]

2 голосов
/ 02 марта 2010

Сколько запросов вы делаете в секунду?

Не могли бы вы просто поместить заблокированное поле в сами записи? Я полагаю, вы все равно получаете запись. Вы также можете использовать что-то вроде memcached для хранения замков.

Я не знаю специфику, но я понимаю, что InnoDB отлично подходит для одновременного чтения, но отстой для одновременного чтения. MyISAM может быть лучше, но моя интуиция говорит мне, что текущий дизайн имеет недостатки.

1 голос
/ 02 марта 2010

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

1 голос
/ 02 марта 2010

Вы пытались запустить EXPLAIN для запросов?

0 голосов
/ 02 марта 2010

Включение мониторов Innodb может помочь сузить причины плохой производительности:

ПОКАЗАТЬ СТАТУС ДВИГАТЕЛЯ INNODB и мониторы InnoDB

...