У меня есть таблица Biggish InnoDB, которая в данный момент содержит около 20 миллионов строк с ~ 20000 новыми строками, вставленными каждый день. Они содержат сообщения для разных тем.Оптимизация таблицы InnoDB и проблемный запрос
CREATE TABLE IF NOT EXISTS `Messages` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`TopicID` bigint(20) unsigned NOT NULL,
`DATESTAMP` int(11) DEFAULT NULL,
`TIMESTAMP` int(10) unsigned NOT NULL,
`Message` mediumtext NOT NULL,
`Checksum` varchar(50) DEFAULT NULL,
`Nickname` varchar(80) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `TopicID` (`TopicID`,`Checksum`),
KEY `DATESTAMP` (`DATESTAMP`),
KEY `Nickname` (`Nickname`),
KEY `TIMESTAMP` (`TIMESTAMP`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=25195126 ;
ПРИМЕЧАНИЕ. В Cheksum хранится контрольная сумма MD5, которая предотвращает одновременное включение одинаковых сообщений в те же темы. (прозвище + отметка времени + тема + последние 20 символов сообщения)
На сайте, который я создаю, есть лента новостей, в которой пользователи могут выбирать для просмотра новейших сообщений от разных псевдонимов с разных форумов. Запроса выглядит следующим образом:
SELECT
Messages.ID AS MessageID,
Messages.Message,
Messages.TIMESTAMP,
Messages.Nickname,
Topics.ID AS TopicID,
Topics.Title AS TopicTitle,
Forums.Title AS ForumTitle
FROM Messages
JOIN FollowedNicknames ON FollowedNicknames.UserID = 'MYUSERID'
JOIN Forums ON Forums.ID = FollowedNicknames.ForumID
JOIN Subforums ON Subforums.ForumID = Forums.ID
JOIN Topics ON Topics.SubforumID = Subforums.ID
WHERE
Messages.Nickname = FollowedNicknames.Nickname AND
Messages.TopicID = Topics.ID AND Messages.DATESTAMP = '2013619'
ORDER BY Messages.TIMESTAMP DESC
ТШЕЗТАМР содержит метку времени Unix и DATESTAMP просто дата генерируется из временной метки Unix для более быстрого доступа через оператор «=» вместо диапазона сканирования с временными метками UNIX.
Проблема в том, что этот запрос занимает около 13 секунд (или более) без буферизации. Это, конечно, неприемлемо для намеренного использования. Добавление DATESTAMP, казалось, ускорило ситуацию, но не сильно.
На данный момент я не знаю, что мне делать. Я читал о составных первичных ключах, но я по-прежнему не уверен, что они будут делать что-то хорошее и как правильно реализовать его в этом конкретном случае.
Я знаю, что использование BIGINT может немного переборщить, но они сильно влияют на это?
EXPLAIN:
+----+-------------+-----------------------+--------+---------------------------------------+------------+---------+-----------------------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------------------+--------+---------------------------------------+------------+---------+-----------------------------------------------+------+----------------------------------------------+
| 1 | SIMPLE | FollowedNicknames | ALL | UserID,ForumID,Nickname | NULL | NULL | NULL | 8 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | Forums | eq_ref | PRIMARY | PRIMARY | 8 | database.FollowedNicknames.ForumiID | 1 | NULL |
| 1 | SIMPLE | Messages | ref | TopicID,DATETIME,Nickname | Nickname | 242 | database.FollowedNicknames.Nickname | 15 | Using where |
| 1 | SIMPLE | Topics | eq_ref | PRIMARY,SubforumID | PRIMARY | 8 | database.Messages.TopicID | 1 | NULL |
| 1 | SIMPLE | Subforums | eq_ref | PRIMARY,ForumID | PRIMARY | 8 | database.Topics.SubforumID | 1 | Using where |
+----+-------------+-----------------------+--------+---------------------------------------+------------+---------+-----------------------------------------------+------+----------------------------------------------+
Что предлагает 'EXPLAIN'? http://dev.mysql.com/doc/refman/5.0/en/explain.html – dash
Добавлен вывод EXPLAIN. –