使用MySQL FULLTEXT覆盖/复合索引

时间:2015-08-20 17:16:02

标签: mysql indexing full-text-search fulltext-index

考虑下表:

CREATE TABLE `item` (
 `id`  bigint(11) unsigned NOT NULL AUTO_INCREMENT,
 `category` smallint(11) unsigned NOT NULL,
 `description` TEXT(500) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `category` (`category`),
 FULLTEXT KEY `fulltextnameindex` (`description`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


INSERT INTO `item` (`id`, `category`, `description`)
 VALUES
(1, 1, 'Nothing here for you'),
(2, 2, 'Still nothing here for you'),
(3, 2, 'this is sometext for you');

要执行全文搜索以匹配类别中sometext字段中的字符串description,请执行以下操作:

SELECT i.id FROM item i 
  WHERE MATCH(i.description) AGAINST ('+sometext*' IN BOOLEAN MODE) AND category IN (2);

这很有效,直到表变大(特别是因为我需要将最小索引字标记大小设置为1或2)。

  1. 有许多类别,各行的分布相当相等
  2. 使用非FULLLTEXT索引,您可以创建复合索引,如果您执行类似CREATE INDEX yippie ON item(category,name)的操作,可以使SELECT i.id FROM item i WHERE category IN (2) AND name LIKE '%sometext%更有效率(请注意,我没有声明&# 39;%sometext%'本身效率很高,但由于复合覆盖索引,类别where子句的查询效率更高。)
  3. 梦想是在categoryname列中都有某种复合索引,例如:CREATE FULLTEXT INDEX yippie ON item(category,name),但这当然不是有效的
  4. 有没有人知道使用FULLTEXT搜索实现#3效果的方法(不为每个类别创建单独的表)?

1 个答案:

答案 0 :(得分:0)

ALTER TABLE ADD FULLTEXT(类别,名称);

http://dev.mysql.com/doc/refman/5.6/en/alter-table.html

注意(在InnoDB中)如果你同时做两件事

MATCH (category) ...
MATCH (category, name)

然后你需要两个

FULLTEXT(category)
FULLTEXT(category, name)

如果您确实更改了ft_min_token_size,请记住重建所有FULLTEXT索引。请参阅innodb_optimize_fulltext_only

name LIKE '%some%'非常慢,因为它会在每个行的中扫描每个 name

如果category是一个数字,请将其放入任何FULLTEXT索引中。 category IN (2) AND MATCH...首先进行FULLTEXT搜索,然后按类别进一步过滤。这应该是充分有效的。