[英]Covering / Composite Indexes with MySQL FULLTEXT
请考虑下表:
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
字段中的字符串sometext
,我运行以下命令:
SELECT i.id FROM item i
WHERE MATCH(i.description) AGAINST ('+sometext*' IN BOOLEAN MODE) AND category IN (2);
这很好,直到表变大为止(特别是因为我需要使最小索引字标记大小为1或2)。
CREATE INDEX yippie ON item(category,name)
在您执行SELECT i.id FROM item i WHERE category IN (2) AND name LIKE '%sometext%
将起作用SELECT i.id FROM item i WHERE category IN (2) AND name LIKE '%sometext%
(注意,我并不是说'%sometext%'本身是有效的,但是由于复合凹口索引,使用where类从句的查询效率更高)。 category
和name
列上都具有某种复合索引,例如: CREATE FULLTEXT INDEX yippie ON item(category,name)
,但这当然是无效的 有谁知道使用FULLTEXT搜索实现#3效果的方法(无需为每个类别创建单独的表)?
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
搜索,然后进一步按类别进行过滤。 这应该足够有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.