SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 24.03.2012 13:17:45

ilan
Участник
Зарегистрирован: 24.03.2012
Сообщений: 2

Медленное удаление MEMORY даже с BTREE индексом.

Доброе время суток всем.

Есть форум на движке phpbbb довольно посещаемый. После проведенного комплекса оптимизаций и изменений узким местом стала таблица сессий. Решил ее сделать MEMORY.  Сейчас перевел обратно ее на INNODB ввиду очень медленного выполнения DELETE. Исходные данные таблицы.

show create table phpbb_sessions_memory;
*************************** 1. row ***************************
       Table: phpbb_sessions_memory
Create Table: CREATE TABLE `phpbb_sessions_memory` (
  `session_id` char(32) NOT NULL DEFAULT '',
  `session_user_id` mediumint(8) unsigned NOT NULL DEFAULT '0',
  `session_last_visit` int(11) unsigned NOT NULL DEFAULT '0',
  `session_start` int(11) unsigned NOT NULL DEFAULT '0',
  `session_time` int(11) unsigned NOT NULL DEFAULT '0',
  `session_ip` varchar(40) NOT NULL DEFAULT '',
  `session_browser` varchar(150) NOT NULL DEFAULT '',
  `session_forwarded_for` varchar(255) NOT NULL DEFAULT '',
  `session_page` varchar(255) NOT NULL DEFAULT '',
  `session_viewonline` tinyint(1) unsigned NOT NULL DEFAULT '1',
  `session_autologin` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `session_admin` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `session_forum_id` mediumint(8) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`session_id`) USING BTREE,
  KEY `session_time` (`session_time`) USING BTREE,
  KEY `session_fid` (`session_forum_id`) USING BTREE,
  KEY `session_user_id` (`session_user_id`) USING BTREE
) ENGINE=MEMORY DEFAULT CHARSET=utf8
1 row in set (0.01 sec)

Заполняем таблицу:
insert into phpbb_sessions_memory select * from phpbb_sessions;
Query OK, 70438 rows affected (0.68 sec)
Records: 70438  Duplicates: 0  Warnings: 0

Сразу после вставки делаю (запрос удаляет значительно меньше строк - уменьшил дельту для демонстрации скорости работы)
DELETE FROM phpbb_sessions_memory WHERE session_user_id =1 AND session_time < (UNIX_TIMESTAMP()-100);
Query OK, 61142 rows affected (0.87 sec)

Здесь удаляется 61142 строк менее чем за секунду.

Но проблема в том, что после активных INSERT, SELECT, UPDATE таблицы удаление таким же запросом занимает несколько секунд. В среднем у меня получалось что удаление 200-300 строк идет 7-8 секунд. Соответственно таблица на это время блокируется и весь форум висит. Причем столько времени удаление занимает даже когда я один в базе. Т.е. дело не в конкуренции и блокировках. Думаю тут проблема в хэшах-индексах mysql на таблицу.

Может быть подскажете что это за затык и как с этим бороться.

MySQL version(): 5.5.21-log

Неактивен

 

#2 24.03.2012 13:42:22

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Медленное удаление MEMORY даже с BTREE индексом.

Попробуйте составной индекс на (session_user_id, session_time)

Неактивен

 

#3 24.03.2012 14:04:26

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Медленное удаление MEMORY даже с BTREE индексом.

Если честно, совсем не верится, что можно удалить 200 строк из таблицы в памяти
за 8 секунд. Даже если они такие длинные, как у Вас. Скорее всего, Вы ждете в
каком-то другом месте. Убедитесь, что именно этот запрос занимает 7 секунд. Я
почти уверен, что сначала он ждет какой-то другой таблицы (или блокировки, напри-
мер), а только потом удаляет уже строки из таблицы сессий. С таблицей в 60к строк
вообще не бывает проблем (ну, если только там не хранятся какие-то большие
тексты).

Неактивен

 

#4 24.03.2012 16:06:04

ilan
Участник
Зарегистрирован: 24.03.2012
Сообщений: 2

Re: Медленное удаление MEMORY даже с BTREE индексом.

Благодарю за внимание к проблеме.

vasya написал:

Попробуйте составной индекс на (session_user_id, session_time)

Попробую, но на expain при таком же селекте он использует индекс session_time с нормальной селективностью.

paulus написал:

Если честно, совсем не верится, что можно удалить 200 строк из таблицы в памяти
за 8 секунд. Даже если они такие длинные, как у Вас. Скорее всего, Вы ждете в
каком-то другом месте. Убедитесь, что именно этот запрос занимает 7 секунд. Я
почти уверен, что сначала он ждет какой-то другой таблицы (или блокировки, напри-
мер), а только потом удаляет уже строки из таблицы сессий. С таблицей в 60к строк
вообще не бывает проблем (ну, если только там не хранятся какие-то большие
тексты).

Это вариант я исключил. Пробовал гасить nginx, show full processlist был пустой. Длительность удаления прямо пропорциональна времени работы сервера. Т.е. чем дольше существует таблица в памяти - тем медленнее удаление.
Размеры таблицы, конечно не радуют. Буду делить ее на 2. Кеш не эффективен при таком количестве обновлений. И из-за varchar размер таблицы в 3-4 раза больше чем в innodb. Размеры varchar в memory вроде решены в percona, но это уже другая тема.

Отредактированно ilan (24.03.2012 16:06:56)

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson