1

我正在COUNT(*)使用MATCH() ... AGAINST(). 我的具体查询如下:

SELECT COUNT(*) FROM `source_code` WHERE MATCH(`html`) AGAINST ('title');

几秒钟后我得到结果:

+----------+
| count(*) |
+----------+
|    17346 |
+----------+
1 row in set (16.30 sec)

多次运行查询后,查询始终需要大约 16 秒才能完成。

有什么方法可以加快这个查询?为什么查询缓存不缓存此查询的结果?

如果有帮助,这里是EXPLAINandCREATE 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 |
+----+-------------+-------------+----------+---------------+--------+---------+------+------+-------------+

看起来正在使用索引。(也许开销是查询仍然是 0Using where正常key_len吗?)

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地方。

4

1 回答 1

1

与许多其他数据库不同,当存在覆盖整个表的索引时,mysql 在处理 select count(*) 查询方面非常出色。在您的情况下,您确实有一个涵盖整个表的索引,但它与普通主键不同,因为它是一个全文索引。

您可以看到查询分析器尝试使用该索引 (possible_keys) 但实际上无法使用它。

key_len 列表示 MySQL 决定使用的密钥的长度。如果键列为 NULL,则长度为 NULL。请注意,key_len 的值使您能够确定 MySQL 实际使用的多部分键的多少部分

key_len为 0 而不是 null是最不寻常的,但这意味着索引的 0 部分用于查询。

至于如何优化这个?答案是非常困难。我唯一能想到的就是创建一个停用词列表,另一个是设置最小字长。这两个都进入你的 my.cnf 文件。

于 2015-10-16T10:12:42.983 回答