我使用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
语句没有太疯狂的
与许多其他数据库不同,当存在覆盖整个表的索引时,mysql非常擅长处理select count(*)查询。在你的例子中,你确实有一个覆盖整个表的索引,但它不同于普通的主键,因为它是一个全文索引。
您可以看到查询分析器试图使用该索引(可能的键),但它实际上无法找到它。
key_len列表示MySQL决定的键的长度使用。如果键列为NULL,则长度为NULL。请注意key_len的值使您能够确定a的多少部分多部分键MySQL实际上使用
最不寻常的是key_len为0而不是null,但这意味着索引的0部分被用于查询。
至于如何优化呢?答案是非常困难。我唯一能想到的是创建一个停止词列表,另一个是设置最小单词长度。这两个都放到my.cnf文件中