谈一谈索引技术

来源:互联网 发布:mysql中触发器的使用 编辑:程序博客网 时间:2024/06/06 01:08

熟悉关系数据库的人应该对索引不陌生。单列索引,多列索引,B树索引,位图索引,事务索引,三星索引等等。读研时期导师就说,索引可以作为一个研究课题搞一辈子。撇开最新的理论创新,即使了解过一些的研究成功,坑需要从一些大部头的著作看起。每年VLDB,sigmod上的关于索引的文章也很多。

本文不打算过于深入,针对常见的一些索引技术做一些总结,算是入门知识吧。

最常见的两种索引数据结构是B+树和LSM-tree。如果从时间复杂度方面对比分析如下:


B+ Tree

LSM Tree

random point read

O(logN)

O(N)

random point write

O(logN)

O(1)

range read / iterator

good

poor when range data is written across long term

batch write

poor when node split

good

     

     从工程实现上:

  • B+树 
    • 优点 B+树的浅层节点具有很好的cache友好性,长时间运行后底层节点一般在memory甚至cpu cache中
    • 缺点 aging问题。叶子节点经过大量的插入删除之后,key range上临近的叶子节点,在磁盘的物理位置是随机的,此时,range查询和batch sequenced write效果都会很差。
  • LSM树
    • 优点 随机批量写入不会导致随机IO。
    • 缺点 主要缺点是compact带来的性能不稳定;一般的compact的实现中,例如base leveled,都会分为minor compact, major(full)compact。full compact可能会阻塞写。对读的性能也有影响。例如rocksdb的默认的level-based compact,写速度受限于L0-->L1 compact的速度,而由于L0文件的L0-L1的compact只能单线程(L0不排序,无法多线程多路归并)。一旦写入速度过快,导致L0 File挤压超过阈值,出发rocksdb write stall机制,写入速度会极大下降。这个问题我在rocksdb社区反应过,没得到很好回应。

     传统的关系数据库,单点查询最为常见,因此一般是采用B+树索引。目前的Big Data兴起以后,LSM Tree逐渐流行起来,HBase, rocksdb是这方面的代表。Big data系统中数据量大,Batch write多。例如hadoop集群上,ETL Job是daily work,批量数据的导入很常见。特别的,监控领域的常用的时间序列数据库,LSM tree的优势更为明显,以时间戳为key,本身写入就是顺序的,甚至不需要compact,只需要按照range drop掉过期的老数据即可。

     随着互联网需求的爆发,各种复杂的应用场景层出不穷。索引的发展也无法八门。在原始的B+和LSM树的基础上有出现了各种变种。例如tokudb的fractal tree,读写性能否分别处于B+树和LSM树之间,一般用来做独立的索引。LSM tree可以把key部分和value部分,算是一个变种例如dgraph-io/badger;pebblesdb也做了一些写方面的性能优化。

      主键索引一般是采用树形索引。secondary index 也可以用B+树。如果是多列,就是BKDTree。构建一个索引的消耗是很高的,尤其是数据的插入删除。目前很多大数据系统是不支持或者在线的二级索引。当然离线索引是可以的,例如kylin,不过构建cube的速度也很慢。

     除了树型索引,位图索引也很场景。BloomFilter其实以一种多维的、每个维度上压缩过的Bitmap。布隆过滤器在hbase ,rocksdb中也很常见。搜索领域的常用的是位图索引的一种变体,例如pilosa 的位图索引,支持high cardinality 数据的位图索引。比如key是一个整数,取值空间是0-2^64,但实际可能的数据量可能只有几个M(2^20)。如果直接用位图,那存储空间是2^64,不现实。pilosa的做法是对key的整数做encode。因为key的个数是有限的,例如只需要100w,那把这100w原始的interger映射到0-2^20的空间,这样只需要一个1M大小的bitmap即可。pilosa非常适合做文本搜索用的倒排索引。

     最后想提下谷歌最新发了篇用深度学习构建数块索引的文章。简单的看了篇论文思想,用DL模拟一个索引能力是可行的,但是离工程实现还很遥远。效率是关键问题,比如数据的频繁的插入和删除,B树的代码实现就很麻烦,那么对于DNN来说,插入和删除时索引是否还有部分有效(B树是可以的),如何retrain,retrain的效率等等,论文还没开始考虑。索引谷歌的最新研究只是一个toy,离工程还很遥远。与之相比,CMU的工作更接地气一些。用机器学习做mysql自动配置优化,并没有对dbms动大手术,oracle也有些类似的工作。

原创粉丝点击