Я только что увидел очень медленный запрос в моем приложении. Таблица «Новости» содержит более 600 000 записей.
Когда я выполняю:
SELECT news.id FROM `news` WHERE (newstime between '2012-01-16 00:00:00' AND '2012-01-16 23:59:59') AND ((MATCH(titolo, testo) AGAINST('"Public Administration" "SOMETHING" "ELSE" "ROMA" "MILANO"' IN BOOLEAN MODE))) ORDER BY newstime DESC LIMIT 23 OFFSET 0;
23 rows in set (26.32 sec)
По какой-то причине MySQL не выполняет выбор диапазона (для каждого дня есть только 10.000 записей), похоже, что он выполняет поиск по всей таблице, потому что, когда я выбираю из подзапроса:
SELECT id FROM(SELECT * from news where newstime between '2012-01-16 00:00:00' AND '2012-01-16 23:59:59') as N where ((MATCH(titolo, testo) AGAINST('"Public Administration" "FIAT" "SOMETHING" "ELSE" "ROMA" "MILANO"' IN BOOLEAN MODE))) ORDER BY newstime DESC LIMIT 23 OFFSET 0;
23 rows in set (0.09 sec)
Мой запрос возвращается через 0,09 секунды!
26 -> 0,09 секунды.
Я думал, что MySQL будет достаточно умен, чтобы выбирать диапазон записей по времени новостей и затем выполнять полнотекстовый поиск, но похоже, что это не так. Это нормально? Или я должен попытаться оптимизировать первый запрос? Когда я пишу объяснение № 1, оно говорит:
mysql> explain SELECT news.id FROM `news` WHERE (newstime between '2012-01-16 00:00:00' AND '2012-01-16 23:59:59') AND ((MATCH(titolo, testo) AGAINST('"Public Administration" "FIAT" "SOMETHING" "ELSE" "ROMA" "MILANO"' IN BOOLEAN MODE))) ORDER BY newstime DESC LIMIT 23 OFFSET 0;
+----+-------------+-------+----------+--------------------------------+---------+---------+------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+----------+--------------------------------+---------+---------+------+------+-----------------------------+
| 1 | SIMPLE | news | fulltext | index_news_on_newstime,alltext | alltext | 0 | | 1 | Using where; Using filesort |
+----+-------------+-------+----------+--------------------------------+---------+---------+------+------+-----------------------------+
Почему используется полнотекстовый ключ, а не новостное время?
Показать новость создания таблицы следующим образом:
CREATE TABLE `news` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`titolo` varchar(255) DEFAULT NULL,
`testo` mediumtext,
`newstime` datetime NOT NULL,
`created_at` datetime DEFAULT NULL
PRIMARY KEY (`id`),
KEY `index_news_on_newstime` (`newstime`),
FULLTEXT KEY `alltext` (`titolo`,`testo`)
) ENGINE=MyISAM AUTO_INCREMENT=1846714 DEFAULT CHARSET=utf8 |
Почему это?