Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Доброе время суток всем.
Есть форум на движке 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
Неактивен
Попробуйте составной индекс на (session_user_id, session_time)
Неактивен
Если честно, совсем не верится, что можно удалить 200 строк из таблицы в памяти
за 8 секунд. Даже если они такие длинные, как у Вас. Скорее всего, Вы ждете в
каком-то другом месте. Убедитесь, что именно этот запрос занимает 7 секунд. Я
почти уверен, что сначала он ждет какой-то другой таблицы (или блокировки, напри-
мер), а только потом удаляет уже строки из таблицы сессий. С таблицей в 60к строк
вообще не бывает проблем (ну, если только там не хранятся какие-то большие
тексты).
Неактивен
Благодарю за внимание к проблеме.
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)
Неактивен
Страниц: 1