《MySQL系列-InnoDB引擎37》索引与算法-全文检索

全文检索

1 概述

对于B+树的特点,可以通过索引字段的前缀进行查找。例如如下的查询方式是支持B+树索引的,只要name字段添加了B+树索引,就可以利用索引快速查找以XXX开头的名称。

select * from table where name like 'XXX%';

而如下这种情况不适合私有B+索引,因为即使添加了B+树索引也是需要进行全文扫描。

select * from table where name like '%XXX%';

但是在实际中会遇到很多这样的场景,例如搜索引擎根据用户输入的关键词进行全文检索,这种都不适合使用B+索引。那就需要引出另一个检索方式,叫全文检索。

全文检索是将存储于数据库中的整本书或整篇文章中的任意内容查找出来的技术。它可以根据需要获得全文中有关章、节、段、句、词等信息,也可以进行各种统计和分析。

最开始InnoDB引擎不支持全文检索技术。需要使用全文检索的表,需要使用MyISAM引擎,但是这却丧失了InnoDB存储引擎的事务性。所以在InnoDB 1.2.x版本开始,InnoDB开始支持全文检索。

2 倒排索引

全文检索通常使用倒排索引(inverted index)来实现。倒排索引同B+树一样,也是一种索引结构。它在辅助表(auxiliary table)中存储了单词与单词自身在一个或多个文档所在位置之间的映射。通常利用关联数组实现,拥有两种表示形式:

  • inverted file index,其表现形式为{单词,单词所在文档的ID}
  • full inverted index,其表现形式为{单词,(单词所在文档ID,在具体文档中的位置)}

例如:下面的例子,表中存储的内容如下:

Documentld表示全文检索文档的ID,text表示存储的内容,用户需要对存储的这些文档内容进行全文检索。

在这里插入图片描述

对于inverted file index的关键数组,其存储的内容容下:

《MySQL系列-InnoDB引擎37》索引与算法-全文检索_第1张图片

可以看到单词code存在于1和4中,这样就可以根据1、4来查找对应的存储内容。对于inverted file index,其仅存取文档ID,而full inverted index存储的是对(pair),即(documentid,position),因此其存储的倒排索引表如下:

《MySQL系列-InnoDB引擎37》索引与算法-全文检索_第2张图片

full inverted index还存储了单词所在的位置信息,如code这个单词出现在(1:6),即文档1的第6个单词为code。相比之下,full inverted index占用更多的空间,但是能更好的定位数据。

3 InnoDB全文检索

InnoDB存储引擎从1.2.x版本开始支持全文检索的技术,其采用full inverted index的方式。在InnoDB存储引擎中,将(DocumentId,Position)视为一个"ilist"。因此在全文检索的表中,有两个列,一个是word字段,一个是ilist字段,并且在word字段上设有索引。此外,由于InnoDB存储引擎在ilist字段中存放了Position信息,故可以进行Proximty Search,而MyISAM存储引擎不支持该特性。

正如之前所说,倒排索引需要将word存放到一张表中,这个表称为Auxiliary table(辅助表)。在InnoDB存储引擎中,为了提高全文检索的并行性能,共有6张Auxiliary table,目前每张表根据word的latin编码进行分区。

Auxiliary Table是持久的表,存放于磁盘上。然而在InnoDB存储引擎的全文索引中,还有另外一个重要的概念FTS Index Cache(全文检索索引缓存),其用来提高全文检索的性能。

FTS Index Cache是一个红黑树,其根据(word,ilist)进行排序。这意味着插入的数据已经更新了对应的表,但是对全文索引的更新可能在分词操作后还在FTS Index Cache中,Auxiliary Table可能还没有更新。InnoDB存储引擎会批量对Auxiliary Table进行更新,而不是每次插入都要更新一次Auxiliary Table。当对全文索引进行查询时,Auxiliary Table首先会将FTS Index Cache中对应的word字段合并到Auxiliary Table中,然后再进行查询。这种merge操作非常类似于之前介绍的Insert Buffer的功能,不同的是Insert Buffer是一个持久的对象,并且其是B+树的结构。然而FTS Index Cache的作用又和Insert Buffer是类似的,它提高了InnoDB存储引擎的性能,并且由于其根据红黑树排序后进行批量插入,其产生的Auxiliary Table相对较小。

你可能感兴趣的:(MySQL,全文检索,mysql,lucene)