PolarDB MySQL limit m,n Top K问题优化
现有的limit m,n处理方式
-
堆排序,topK算法
-
归并排序时基于offset和limit做truncate
- Self-sharpening input filter算法
假如有若干个sorted run有序数组,则取第K大的元素(这个元素称为cutoff value)以及之前的值,其余的值都过滤掉,然后再用这个cutoff value值过滤其他sorted run数组的值,并更新cutoff value(如果其他sorted run的第K个值小于cutoff value的话)。如此循环,不断用cutoff value过滤掉更多的值。
当K大于sorted run的长度时,会合并足够多的sorted run,然后执行上述流程,更新 cutoff value值。
现有方案存在的问题
1. 当内存充足,采用优先队列的TopK算法时,需要维护非常大的优先队列,队列操作对内存的访问操作是乱序的,访存效率较差,影响算法实际运行的性能。
2. 内存不足时,使用归并排序+truncate 的方案,当时当offset 大于sorted run的长度时,则需要足够多的sorted run才能合并成满足条件的数组,影响truncate效率。
解决
-
基于SIMD(单指令流多数据流)的Self-sharpening input filter
-
基于ZoneMap的Pruning
先假设已知位于offset的值(称为offset)和offset+limit的值(称为limit) 已知有若干sorted run数组,则可知sorted run中最大值(barrier1)小于offset一定不在所求结果集内,sorted run最小值大于limit的值(barrier2)也不在所求结果集内。因此只需寻找offset和limit值位于sorted run之间的哪些sorted run即可。 因此,只需找一个尽可能大的barrer1满足barrer1<offset值,以及一个尽可能小的barrer2满足barrer2>limit值,然后将能够覆盖这两个值的sorted run进行合并。
- 参考http://mysql.taobao.org/monthly/2023/01/02/****