#算法
HyperLogLog算法是被广泛使用来估算一组数据里有多少不相同值(distinct value)的算法,可以参考这里的讲解:https://www.yuque.com/abser/aboutme/nfx0a4
它用较小的数据量实现了不差的预估准确率。
比如要估算一天有多少不同的页面被访问(注意不是被访问的次数),这个算法就派上了用场。
在数据库里,要优化一个查询计划时,也需要知道被访问的表里每一列有多少不同的值来指定查询计划,于是也需要用到这个这个算法。
但是原始的HyperLogLog实现并不支持删除数据,比如一个表每一列原先的预估是一个值,但是也得考虑这个表被删除一些数据之后算一个新的预估值。
论文《Every Row Counts: Combining Sketches and Sampling for
Accurate Group-By Result Estimates》给出了一个大体的解决思路:
* 可以在每个值加一个计数器(counter)。
* 但是如果每个值的计数器是8Byte的话,就需要新增30KB的容量来存储计数,违背了HyperLogLog的初衷:小代价实现估算。
* 于是论文里提出这个计数器只需要1Byte,这1Byte的前128的值是精确存储,后128存的只是概率值。换成1Byte之后,成本从30KB降到了3.6KB。
我把Rust的HyperLogLog库streaming_algorithms fork下来在其基础上提供了delete的实现,diff见:https://github.com/datafuse-extras/streaming_algorithms/commit/762a59c5e65b36797a1ee1cad6fc410c62c9a8b9
貌似这应该是业内第一份不限语言的hll delete实现:)
Post #367
3.13K