sphinx搜索引擎索引结构优化

原创,转载请以连接形式标明作者和出处!

2年前工作中的内容,已成过眼烟云,分享一下,欢迎交流。

sphinx的倒排索引采用紧凑的磁盘存储方式,其docid采用增量压缩方式存储与.spd文件中。

sphinx2.0.1官方版本的.spd文件有三种数据结构:

结构1》[ DocID + (Attr) + HitPosList_Offset + FieldCount + HitCount ] + […] + …

DocID:4或8字节, 增量压缩值(与前一个DocID的差值)

(Attr):属性内容,可配置字段。定长长度,根据具体配置指定,设置属性内联则有该字段。

HitPosList_Offset: 4或8字节,增量压缩值(与前一个HitPosList_Offset的差值)

FieldCount:4字节,压缩值

HitCount: 4字节,为压缩值

结构2》[ DocID + (Attr) + HitCount(1) + HitPos ] + […] + …

DocID:4或8字节,为增量压缩值(与前一个DocID的差值)

(Attr):属性内容,可配置字段。定长长度,根据具体配置指定,设置属性内联则有该字段。

HitCount:4字节,压缩值,此格式该值永远为1

HitPos:4字节,压缩值

结构3》[ DocID + (Attr) + HitCount + FieldCount + HitPosList_Offset ] + […] + …

DocID:4或8字节,增量压缩值(与前一个DocID的差值)

(Attr):属性内容,可配置字段。定长长度,根据具体配置指定,设置属性内联则有该字段。

HitCount:4字节,压缩值

FieldCount:4字节,压缩值

HitPosList_Offset : 4或8字节,压缩值

其中,xx搜索采用了数据结构一。

检索过程中,对查询树进行query_node间的"与"、"或"运算,sphinx采用了多层调用,多路归并的方法来完成。多层调用带来大量的赋值操作,CPU消耗巨大。由于微博本身短小,检索过程只需要使用结构一中的DocID值,不需要HitCount、FieldCount、HitPosList_Offset几个字段,大量赋值操作是没有意义的。因此对spd文件结构进行精简,只保留DocID字段。

xx搜索中有很多条件匹配,多是通过属性字段检索来完成,为了找到符合某属性条件的docid,会进行docid->属性之间的二分查找(微博系统docid本身不连续,无法直接使用docid->属性这种映射,因此只能查询.spa文件的hash索引,该索引在系统启动时创建),当查询节点较多,要求返回结果较大的情况下,二分查找带来的cpu时间消耗是很大的。对于这个问题的解决需要先看一下.spa文件的数据结构:

[DocID0 + mva0_offset + mva1_offset+…attr0+attr1…] + [DocID1 + mva0_offset + mva1_offset+…attr0+attr1…] + [DocID2…] + [DocID3…] + …

DocID:4或8字节。

mvaX_offset:X个8字节,多值属性X在spm中起始偏移。

attrM:M个4字节,固定个数的属性

从数据结构可看出,DocID+属性的分段中DocID是递增的,一个DocID对应着一个属性下标号。因此在.spd文件中直接使用该下标号替代DocID是可行的。.spd中的数据结构长度固定,在检索系统启动时被加载到固定大小的数组中,因此在检索过程中,从.spd文件中取到了一个属性下标号,就可以直接使用这个下标在内存中取到属性内容,不需要再进行查找。

以上对索引数据的修改,涉及到sphinx的索引创建indexer部分。

在创建索引过程中,获取DocID->属性下标的信息,使用AVL树进行存储,在需要写spd文件的DocID增量时查找该树取出下标号并做增量后做为DocID写入,索引创建完成后,释放该树的资源。

在这个过程中有一个隐蔽的问题,.spd文件中标示每个倒排列表结束的0,在检索过程解压倒排列表的时候,当遇到0时既标示倒排列表结束。也就是0在这里有特殊的含义。通过查看spd的文件结构知道,spd在写入倒排列表前,会在文件的最开始写入一个无用的占位字节,目的是为了防止出现偏移为0这类问题,而.spa中的属性下标就是从0开始,所以,使用属性下标替代DocID后可能会出现“docid”差值为0的情况,解决这个问题较简单,只需要在写入属性下标增量时做一个+1操作,在检索过程中,先判断是否是遇到0,当不是0的情况下,将这个获取到的下标号再减1,以此来解决这个隐蔽的问题。

时间: 2024-10-30 22:03:47

sphinx搜索引擎索引结构优化的相关文章

sphinx搜索引擎优化及测试

原创,转载请务必保留作者及本文出处(连接形式). 2年前工作中的内容,已成过眼烟云,分享一下,欢迎交流. 1.之前的优化效果 之前对sphinx线程处理,网络IO做了很多优化(netty.epoll.libevent),索引部分也做了优化,从目前测试结果来看,性能提升已经到了瓶颈,尤其是全部搜索,线程调度,网络 IO优化对于这种查询方式帮助很小.对于单节点性能提升,还得从索引本身查询算法入手优化.sphinx的属性过滤对性能本身有很大影响,但是优化空间不 是很大,读取的属性是离散的,不像索引是可

mysql索引结构原理、性能分析与优化

原文  http://wulijun.github.com/2012/08/21/mysql-index-implementation-and-optimization.html 第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页查阅找出需要的资料. 唯一索引(unique index) 强调唯一,就是索引值必须唯一. 创建索引: create unique index 索引名 on 表名(列

由浅入深探究mysql索引结构原理、性能分析与优化

转载自:http://www.phpben.com/?post=74 第一部分:基础知识: 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里,不用一页一页查阅找出需要的资料.关键字index ------------------------------------------------------------- 唯一索引 强调唯一,就是索引值必须唯一,关键字unique index 创建索引: 1.create unique

[转]mysql索引结构原理、性能分析与优化

第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页查阅找出需要的资料. 唯一索引(unique index) 强调唯一,就是索引值必须唯一. 创建索引: create unique index 索引名 on 表名(列名); alter table 表名 add unique index 索引名 (列名); 删除索引: drop index 索引名 on 表名; alter table 表名 d

转:由浅入深探究mysql索引结构原理、性能分析与优化

摘要: 第一部分:基础知识 第二部分:MYISAM和INNODB索引结构 1. 简单介绍B-tree B+ tree树 2. MyisAM索引结构 3. Annode索引结构 4. MyisAM索引与InnoDB索引相比较 第三部分:MYSQL优化 1.表数据类型选择 2.sql语句优化 (1)     最左前缀原则 (1.1)  能正确的利用索引 (1.2)  不能正确的利用索引 (1.3)  如果一个查询where子句中确实不需要password列,那就用“补洞”. (1.4)  like

由浅入深探究 MySQL索引结构原理、性能分析与优化

第一部分:基础知识: 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里,不用一页一页查阅找出需要的资料.关键字index --------------------- 唯一索引 强调唯一,就是索引值必须唯一,关键字unique index 创建索引: 1.create unique index 索引名 on 表名(列名); 2.alter table 表名 add unique index 索引名 (列名); 删除索引: 1.

由浅入深探究mysql索引结构原理、性能分析与优化(转)

add by zhj:原文链接已经失效了,网上看到的都是转载,向作者Benwin致敬 摘要: 第一部分:基础知识 第二部分:MYISAM和INNODB索引结构 1.简单介绍B-tree B+ tree树 2.MyisAM索引结构 3.Annode索引结构 4.MyisAM索引与InnoDB索引相比较 第三部分:MYSQL优化 1.表数据类型选择 2.sql语句优化 (1)     最左前缀原则 (1.1)  能正确的利用索引 (1.2)  不能正确的利用索引 (1.3)  如果一个查询where

【转】由浅入深探究mysql索引结构原理、性能分析与优化

摘要: 第一部分:基础知识 第二部分:MYISAM和INNODB索引结构 1.简单介绍B-tree B+ tree树 2.MyisAM索引结构 3.Annode索引结构 4.MyisAM索引与InnoDB索引相比较 第三部分:MYSQL优化 1.表数据类型选择 2.sql语句优化 (1)     最左前缀原则 (1.1)  能正确的利用索引 (1.2)  不能正确的利用索引 (1.3)  如果一个查询where子句中确实不需要password列,那就用“补洞”. (1.4)  like (2)

SqlServer索引及优化详解

(一)深入浅出理解索引结构 实际上,您可以把索引理解为一种特殊的目录.微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引.簇集索引)和非聚集索引(nonclustered index,也称非聚类索引.非簇集索引).下面,我们举例来说明一下聚集索引和非聚集索引的区别: 其实,我们的汉语字典的正文本身就是一个聚集索引.比如,我们要查“安”字,就会很自然地翻开字典的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字母“a”开头并以“z”