性能优化技巧 - 查找( 三 )


选项@2、@3的意思分别是将索引的第二、三级缓存先加载进内存 。经过索引缓存的预处理,第一遍查询时间也能达到查询数百次后才能达到的极限值 。@2相比@3缓存的内容少,效果相对差一点,但内存占用也更少 。使用时需要程序员根据具体场景来权衡@2还是@3 。

性能优化技巧 - 查找

文章插图
 
代码3.1
代码3.1,基于代码2.10建造的组表文件,不使用索引缓存,查询耗时为31883毫秒 。
性能优化技巧 - 查找

文章插图
 
代码3.2
代码3.2使用第三级索引缓存,查询耗时为5225毫秒 。
这里使用的是列存组表,列存采用了数据分块并压缩的算法,对于遍历运算来讲,访问数据量会变小,也就会具有更好的性能 。但对于基于索引随机取数的场景,由于要有额外的解压过程,而且每次取数都会针对整个分块,运算复杂度会高很多 。因此,从原理上分析,这时候的性能应当会比行存要差 。将组表转为行存后,查询耗时仅为1592毫秒 。
索引缓存在并行时可以复用,如下:
性能优化技巧 - 查找

文章插图
 
代码3.3
代码3.3,并行时,A5的每个线程中都可以使用A2、A3中建立的第三级索引缓存,最终查询耗时为21376毫秒 。
4 带值索引
组表的行存和列存形式都支持索引,列存索引查找比行存性能差,返回结果集较少时差异不明显,大量返回时会有明显劣势,在设计存储方案时要权衡 。
性能优化技巧 - 查找

文章插图
 
代码4.1
代码4.1建立组表文件id_600m.ctx,结构为(#id,data),包含6亿条记录,其中:
A1:包含 26 个英文字母和 10 个阿拉伯数字的字符串 。
A2、A3:建立结构为 (id,data) 的组表文件,使用列式存储方式 。
A4:循环 6000 次,循环体B4、B5,每次生成 10 万条对应结构的记录,并追加到组表文件 。
执行后,生成组表文件:id_600m.ctx
性能优化技巧 - 查找

文章插图
 
代码4.2
代码4.2为组表id列建立索引 。
执行后,生成组表的索引文件:id_600m.ctx__id_idx 。
列存组表生成时 create() 函数加上 @r 选项,即可变为生成行存组表,其余代码无异,这里不再举例,当返回数据量较大时:
性能优化技巧 - 查找

文章插图
 
代码4.3
代码4.3中,列存查询耗时和行存查询耗时,也就是A5和A9的值分别为205270和82800毫秒 。
组表支持一种带值索引,即把查找字段也写入索引,这样可以不再访问原组表即返回结果 。但存储空间会占用较多 。
基于代码4.1的列存组表文件id_600m.ctx 。
性能优化技巧 - 查找

文章插图
 
代码4.4
代码4.4为组表id列建立索引,在对组表建立索引时,当 index 函数有数据列名参数,如本例 A2 中的 data,就会在建索引时把数据列 data 复制进索引 。当有多个数据列时,可以写为:index(id_idx;id;data1,data2,…) 。
因为在索引中做了冗余,索引文件也自然会较大,本文中测试的列存组表和索引冗余后的文件大小为:
性能优化技巧 - 查找

文章插图
 
当数据复制进索引后,实际上读取时不再访问原数据文件了 。
从 6 亿条数据总量中取 1 万条批量随机键值,完整的测试结果对比:
性能优化技巧 - 查找

文章插图
 
5 批量键值
组表索引能够识别出contain式条件,支持批量等值查找 。
性能优化技巧 - 查找

文章插图
 
代码5.1
代码5.1建立组表文件id_600m.ctx,结构为(#id,data),包含6亿条记录,其中:
A1:包含 26 个英文字母和 10 个阿拉伯数字的字符串 。
A2、A3:建立结构为 (id,data) 的组表文件,@r 选项表示使用行式存储方式 。
A4:循环 6000 次,循环体B4、B5,每次生成 10 万条对应结构的记录,并追加到组表文件 。
执行后,生成组表文件:id_600m.ctx 。
性能优化技巧 - 查找

文章插图
 
代码5.2
代码5.2为组表id列建立索引 。


推荐阅读