Оптимизировать COUNT(*) с помощью MATCH ... ПРОТИВ
Я использую COUNT(*)
с MATCH() ... AGAINST()
, Мой конкретный запрос выглядит следующим образом:
SELECT COUNT(*) FROM `source_code` WHERE MATCH(`html`) AGAINST ('title');
Я получаю результаты через несколько секунд:
+----------+
| count(*) |
+----------+
| 17346 |
+----------+
1 row in set (16.30 sec)
После многократного выполнения запроса на его выполнение всегда уходит около 16 секунд.
Есть ли способ ускорить этот запрос? Почему кеш запросов не кэширует результаты этого запроса?
В случае, если это полезно, вот EXPLAIN
а также CREATE TABLE
заявления:
EXPLAIN SELECT COUNT(*) FROM `source_code` WHERE MATCH(`html_w`) AGAINST ('title');
+----+-------------+-------------+----------+---------------+--------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+----------+---------------+--------+---------+------+------+-------------+
| 1 | SIMPLE | source_code | fulltext | html | html | 0 | | 1 | Using where |
+----+-------------+-------------+----------+---------------+--------+---------+------+------+-------------+
Похоже, индекс используется. (Может быть, накладные расходы на то, что запрос все еще Using where
? Это нормально для key_len
быть 0?)
SHOW CREATE TABLE `source_code`;
CREATE TABLE `source_code` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`url` varchar(255) NOT NULL,
`domain` varchar(255) DEFAULT NULL,
`title` varchar(255) DEFAULT NULL,
`html` longtext,
`crawled` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `url` (`url`),
KEY `crawled` (`crawled`),
KEY `domain` (`domain`),
FULLTEXT KEY `html` (`html`)
) ENGINE=MyISAM AUTO_INCREMENT=78707 DEFAULT CHARSET=latin1
Ничего слишком сумасшедшего в CREATE TABLE
заявление.
1 ответ
В отличие от многих других баз данных, MySQL очень хорошо обрабатывает запросы на выборку (*), когда существует индекс, охватывающий всю таблицу. В вашем случае у вас есть индекс, который охватывает всю таблицу, но он отличается от обычного первичного ключа, так как это полнотекстовый индекс.
Вы можете видеть, что анализатор запросов пытается использовать этот индекс (возможных_ключей), но на самом деле он нам не в состоянии.
Столбец key_len указывает длину ключа, который MySQL решил использовать. Длина равна NULL, если в ключевом столбце указано NULL. Обратите внимание, что значение key_len позволяет вам определить, сколько частей ключа из нескольких частей фактически использует MySQL.
Для key_len очень необычно быть 0 вместо нуля, но это означает, что 0 частей вашего индекса были использованы для запроса.
Что касается того, как оптимизировать это? Ответ очень сложный. Единственное, о чем я могу думать, - это создать список стоп-слов, а другое - установить минимальную длину слова. Оба они входят в ваш файл my.cnf.