文章目录
ABSTRACT
我们提出了第一个支持前身、范围查询和更新的学习型索引,在最坏的情况下,在可证明的有效时间和空间范围内。在只有前身和范围查询的(静态)情况下,这些界限被证明是最佳的。我们把这个学习到的索引称为分片几何模型索引(PGM-index)。其灵活的设计使我们能够引入三种变体,这在学习数据结构的背景下是很新颖的。PGM-index的第一个变体能够适应查询操作的分布,从而产生了迄今为止第一个已知的分布感知的学习索引。第二个变体利用了可能存在于组成PGM-指数的学习模型层面的重复性,进一步压缩了其简洁的空间足迹。第三种是PGM指数的多标准变体,它能在几秒钟内对数以亿计的键进行有效的自动调整,以满足随着用户、设备和应用的变化而变化的时空限制。
这些理论成果得到了在已知数据集上的大量实验结果的支持,这些实验结果表明,完全动态的PGM-索引将现有的传统索引和学习型索引的空间占用率提高了三个数量级,同时仍然实现了相同甚至更好的查询和更新时间效率。例如,在前人和范围查询的静态设置中,PGM-指数与缓存优化的静态B+树的查询性能相匹配,但却减少了两个数量级(83倍)的空间;而在允许插入和删除的完全动态设置中,PGM-指数将B+树的查询和更新时间性能提高了71%,却减少了三个数量级(1140倍)的空间。
1. INTRODUCTION
具体来说,我们设计了一个完全动态的学习指数,即分片几何模型指数(PGM-index),它根据一个新的递归结构中固定的最大误差容忍度来协调线性模型的最佳数量(第2和第3节)。根据[32]所证明的下限,PGM-index以I/O优化的方式解决了前身搜索问题,同时占用了简洁的空间。此外,它的新设计使它成为一个完全学习的索引(不像RMI和FITing-tree那样混合了传统和学习的设计元素),它使我们能够引入新的技术,使其压缩(第4节),不仅对密钥分布,而且对查询分布也有适应性(第5节)。然后,我们表明PGM-索引可以根据任何给定的空间或延迟要求有效地自动调整自己(第6节)。
我们在高达10亿个密钥的合成和真实世界数据集上测试了PGM-index的效率(第7节)。简而言之,PGM-index的实验成果是。(i) 比FITing树[17]的空间占有率高75%,比CSS树[33]的空间占有率高83倍,查询时间相同或更好;(ii) 在查询时间和空间占有率方面统一改进了RMI[22]的性能,构建速度快15倍,同时不需要调整超参数;(iii) 在各种动态工作负载中,查询和更新时间比B+树高71%,同时空间占有率降低四个数量级(从数千字节到数兆字节)
2. PGM-INDEX
假设S是一个从宇宙U中抽取的n个键的多集,2 PGM-index是一个以整数ε≥1为参数的数据结构,它解决了S上的完全可索引字典问题,如第1节所定义。
让A是一个排序的数组,存储S的(可能是重复的)键。PGM-index的第一要素是一个分片线性近似模型(PLA-model),即U中的键和它们在数组A中的近似位置之间的映射。具体来说,我们的目标是学习一个映射,返回一个键k∈U的位置,该位置与A中的正确位置最多相差ε。我们说分片线性,是因为一个单一的线性模型(也称为段)可能不足以ε-近似U中所有键的位置。因此,PGM-index学习了一连串的段,每个段需要恒定的空间(两个浮点和一个键)和恒定的查询时间来返回K在A中的ε-近似位置。我们在下面的Lemma 1中表明,存在一个线性时间和空间算法来计算最佳的PLA模型,即由最少的ε-近似段组成的模型。我们还注意到,由最优PLA模型返回的ε-近似位置可以通过二进制搜索在A中的±ε键范围内变成精确位置,因此需要的时间是参数ε的对数,与n无关。
总的来说,每个PLA模型构成PGM指数的一个层次,而该PLA模型的每个片段构成该层次的数据结构的一个节点。这种递归结构相对于已知的学习指数建议(参见FITing-tree或RMI)的特殊性在于PGM-指数是一个纯粹的学习指数,在其结构中(如FITing-tree)或在ML模型错误过多时(如RMI)不依赖于经典数据结构。其净结果是影响其时空复杂性的三个主要优势。首先,PGM索引使用线性模型(即段)作为数据结构各级的恒定空间路由表,而其他索引(如FITing-tree、B-tree和变体)使用的是存储大量键的空间消耗型节点,这只取决于磁盘页的大小,因此导致对数据分布中可能存在的规律性视而不见。第二,PGM-index的这些路由表需要恒定的时间来将节点中的键的搜索限制在一个较小的键子集(大小为2ε),而B+树和FITing树中的节点会产生一个随节点大小而增长的搜索成本,从而在查询操作中减慢了树的遍历。第三,在本文中,我们观察到计算最小段数是一个众所周知的计算几何问题,它在线性时间和空间上都有一个最优解,因此超过了FITing-tree和RMI的次优方案。
下面两个小节详细介绍了PGM-索引的构造和查询操作,第三节讨论了插入和删除。
2.1 Optimal PLA-model
在这一节中,我们描述了如何有效地计算和简洁地存储从键到A中的位置的映射等级的ε-近似实现,这是PGM-索引的核心设计要素之一。
如图1所示,段s是一个三要素(键、斜率、截距),通过函数fs(k)=k×斜率+截距来索引U的范围。PGM指数的一个重要特征是其分段的 "精度 "ε。
定义 1.让A是一个从宇宙U中抽取的n个键的排序数组,让ε≥1是一个整数。一个段s = (key, slope, intercept)被称为提供了[ki, ki+r]中所有键的范围的一个ε近似索引。
我们注意到,段所提供的ε-近似索引并不仅仅适用于A中的键,而是适用于U中的所有键。 因此,一个段可以被看作是一个近似的前身搜索数据结构,其覆盖的键的范围提供了O(1)的查询时间和O(1)的占用空间。然而,一个段可能不足以对A中的整个键集进行ε-近似的等级函数;因此,我们看一下段序列的计算,也称为PLA-model。
定义2。给定ε≥1,分段线性ε-近似问题包括计算PLA模型,该PLA模型最小化其片段{s0,…,sm−1}的数量,前提是每个片段sj对于S中的键的覆盖范围是ε-近似的。这些范围是不相交的,并且一起覆盖整个宇宙U。
找到一个数组A的最佳PLA模型的方法是通过动态编程,但是它所需要的O(n3)时间是非常大的。FITing-tree[17]的作者通过一种启发式的方法来解决这个问题,这种方法在时间上是线性的,但是不能保证找到最优的PLA模型,而且实际上它的表现也很差(正如我们在第7.1节中所展示的)。
有趣的是,我们发现这个问题在时间序列的有损压缩和相似性搜索方面已经得到了广泛的研究(例如,见[28, 9, 11, 12, 39]和其中的参考文献),并且它承认流算法需要O(n)最佳时间和空间。这一系列方法的关键思想是将分片线性ε-逼近问题简化为构建点集合的凸壳问题,在我们的例子中,凸壳是i=0, …, n-1时逐渐增长的集合{(ki, rank (ki)}。, n-1. 只要凸壳可以被包围在一个高度不超过2ε的(可能是旋转的)矩形中,指数i就会被递增,并且集合被扩展。一旦包围凸壳的矩形高度超过2ε,我们就停止构建,并确定PLA模型的一个部分,即把该矩形分割成两个大小相等的部分的线。然后,当前的处理元素集被清空,算法从其余的输入点重新开始。这种贪婪的方法可以被证明在PLA模型的大小上是最优的,并且具有线性的时间和空间复杂性。在我们的背景下,我们可以把这个结果重新表述如下。
定理1(Opt. PLA-model [28])。给出一个序列{(xi, yi)}i=0,…,n-1,这些点的x坐标是不递减的。存在一种流算法,可以在线性时间和空间内计算出ε-近似于该序列中每个点的y坐标的最小段数。
对于我们在字典问题上的应用,Lemma 1中的xis对应于输入键ki,yis对应于它们在排序的输入数组A中的位置0, . . . 下一步是证明一个简单但非常有用的约束,即最佳PLA模型的一段所覆盖的键的数量,我们在分析PGM-指数时使用这个约束。
定理2. 给出一个键的有序序列ki∈U和相应的序列{(ki, i)}i=0,…,n-1,这些点在笛卡尔平面内的坐标都是不递减的。定理1的算法确定了一个(最小)的段数mopt,每个段至少覆盖2ε个点,所以最小段数mopt≤n/(2ε)。
2.2 Indexing the PLA-model
Lemma 1的算法将输入数组A的最优PLA模型返回为m段的序列M = [s0, …, sm-1]。现在,为了解决完全可索引字典的问题,我们需要找到负责估计查询键k的近似位置的ε-近似段sj,这是最右边的段sj,使sj.key≤k。在后一种情况下,对这个数据结构的查询将需要O(logB m + log(ε/B)) I/O,其中B是多路树的扇出量,ε是近似等级(k)时一个片段产生的误差。
然而,上面的索引策略并没有充分利用键的分布,因为它采用了一个具有固定扇出的经典数据结构来索引M。因此,我们引入了一种新的策略,它包括在从片段序列中得到的一组键上递归地重复分片线性近似过程。更确切地说,我们从在整个输入数组A上构建的序列M开始,然后提取A的第一个键被每个段覆盖,最后在这个减少的键集合上构建另一个最优的PLA模型。我们以这种递归的方式进行,直到PLA模型由一个段组成,如图2的伪代码所示。
如果我们把段映射到节点上,那么这种方法就构建了一种多路搜索树,但相对于B树(因此也相对于FITing树)有三个主要优势。(i) 它的节点有可变的扇形,由与这些节点相关的段所覆盖的键的数量(通常很大)所驱动;(ii) 一个节点中的段对要支持的各种查询起着恒定空间和恒定时间的ε-近似路由表的作用;(iii) 每个节点中的搜索通过二进制搜索纠正该路由表返回的ε近似位置(见下文),因此它的时间成本取决于对数的ε,与相应段所覆盖的键数量无关。
现在,对这个递归PGM-索引的查询操作如下。在每一级,它使用指向被访问节点的段来估计被搜索的键k在下一级的键中的位置。考虑到下一层的每个键都是该层的段所覆盖的第一个键,我们已经确定了下一个要查询的段,这个过程一直持续到最后一层。图2中描述了查询操作的伪代码和一个例子。
Theorem 1.//
PGM索引的主要创新之处在于它的空间开销并不像第一节提到的传统索引那样随n线性增长,而是取决于输入数组A的 “规则性趋势”。由于这一事实对于递归层也是成立的,因此,PGM-index在空间和时间上不可能渐进地比2ε-way树,如FITing树、B+树或CSS树更差(只要在定理1中取c=2ε=Θ(B))。因此,根据文献[32]所证明的下限,我们可以说PGM-index以I/O最优的方式解决了具有前身搜索的完全可索引字典问题,这意味着它有可能在几乎没有性能下降的情况下取代任何现有索引。
表1总结了PGM指数及其竞争对手在随机存取机(RAM)和外部存储器(EM)模型中的点查询的界限。第7节的实验结果进一步支持了这些理论成果,表明PGM-index比FITing-tree、B±tree和CSS-tree更快、更简洁,因为在实践中,mopt 远小于 n和递归结构保证了c 远大于 2ε.
3. DYNAMIC PGM-INDEX(插入和删除)
与传统索引相比,PGM-索引中的插入和删除更难实现。首先,一个段可以索引一个可变的、可能很大的数据子集,这一事实使得经典的B树节点拆分和合并算法不适用,因为它们确实依赖于一个节点包含固定数量Θ(B)的键的事实。我们确实可以强制分段覆盖固定数量的键,但这将瓦解PGM-索引的索引能力。现有的学习型索引建议为每个节点(模型)在一个排序的缓冲区中插入新的元素,并不时地与主索引合并,从而导致相应模型的重新训练[17, 22]。当一个模型索引了许多键(因此它的再训练很慢),或者当插入的键空间的某个区域(因此由于快速填充少数缓冲区而导致许多合并),这种解决方案是低效的。在本节中,我们提出了两种处理更新的改进策略,一种针对时间序列,另一种针对更普遍的动态场景。
如果新的键被添加到数组A的末尾,同时保持排序的顺序(就像在时间序列中发生的那样),PGM-index会在O(1)的摊销时间内更新最后一个段[28]。如果新的键k可以被这个最后的段所覆盖,同时保留了ε的保证,那么插入过程就会停止。否则,将创建一个带有密钥k的新段。然后,在上面一层的最后一个网段中递归地重复插入k的过程。当任何一层的段在ε保证范围内覆盖k,或者到达根段时,递归就会停止。在这一点上,根段可能需要拆分,并创建一个新的根节点与它相应的段。由于每一级的工作都需要恒定的摊销I/O,所以这种插入算法所需的I/O总数是O(logc m)的摊销数。、
对于发生在A的任意位置的插入,我们使用在[29,26]中提出的对数方法,在此对其进行调整以适用于学习型索引。我们定义了一系列的PGM索引,这些索引建立在键的集合S0, … , Sb的键,这些键要么是空的,要么是大小为20, 21, … , 2b,其中b =Θ(log n)。 由于Sjs是被排序的(0≤j < i),这个联合可以在与合并集的大小成线性关系的时间内被计算出来。新的排序集由2i个键组成(鉴于2i = 1 + Pi-1 j=0 2j)。新的合并集被用作Si,而之前的集合被清空。如果我们考虑一个键并检查它在n次插入中的历史,我们注意到它最多可以参与b =Θ(log n)次合并,因为每次合并都会将键移到右边的索引上,而完整的Slog n可能包括所有插入的键。鉴于合并需要的时间与被合并的键的数量成线性关系,我们在每次合并时为每个键支付O(1)的摊销时间,也就是说,每次插入的摊销时间为O(log n)。
对一个键d的删除处理与插入类似,通过添加一个特殊的墓碑值来表示对d的逻辑删除,关于细节,我们请读者参考[29]。
对于范围查询,在每个Sis中进行搜索并通过大小为b的堆进行排序合并就足够了,其成本为O(log n(log m+ logε) + K log log n)时间,其中K是满足范围查询的键的数量。如果范围查询的结果可以在O(K)空间中缓冲,那么成本就降低到O(log n(log m+logε)+K)时间。
4. COMPRESSED PGM-INDEX
压缩PGM-指数归根结底是为键和段(即截距和斜率)提供适当的无损压缩器,它们构成了我们学习数据结构的组成部分。在这一节中,我们提出了专门针对片段压缩的技术,因为键的压缩是一个正交的问题,存在着大量的解决方案。
关于压缩截距的问题,我们的做法如下。截距可以通过使用段的坐标系统来增加,即对于一个段sj = (key j, slope j, intercept j)计算被其覆盖的键k的位置为fsj (k) = (k- key j) × slope j + intercept j.然后,由于fsj (k)的结果必须被截断以返回A中的整数位置,我们将截距存储为整数bintercept jc。最后,我们利用截距小于n的事实,从而使用[25]的简洁的数据结构,得到以下结果。
命题1. 假设m是一个PGM索引的段数,该索引从宇宙U中抽取了n个键,这些段的截点可以用m log(n/m)+1.92m+o(m)位来存储,并且可以在O(1)时间内随机访问。
斜率的压缩涉及的内容更多,我们需要设计一种具体的新的压缩技术。开始的观察是,Lemma 1的算法计算的不仅仅是一个单一的线段,而是整个ε近似线段家族,其斜率确定了一个实数的区间。具体来说,我们假设m个最优段的斜率区间为I0 = (a0, b0), … . Im-1 = (am-1, bm-1),因此每个原始斜率j都属于Ij,j = 0, . . , m- 1. 我们的压缩算法的目标是通过将这些斜率的不同数量从m减少到t来减少这些斜率集合的熵。给定t个斜率,我们可以将它们存储在一个表T [0, t- 1]中,然后将每个原始斜率j的编码改为这t个斜率之一的编码,例如斜率0 j,它仍然保证属于Ij,但现在它可以用dlog te比特编码(作为表T的一个指针)。我们将在第7.4节中通过实验证明,该算法实现了有效的压缩,因为t 远小于 m。
现在让我们来描述一下这个算法。首先,我们对斜率区间Ijs进行按字母顺序的排序,得到一个数组I,其中重叠的区间是连续的。我们假设每一对都保留相应区间的索引作为卫星信息,即j代表(aj,bj)。然后,我们对I进行扫描,以确定I中相互交叉的区间的最大前缀。作为一个例子,假设排序的斜率区间是{(2, 7), (3, 6), (4, 8), (7, 9), . . . }. 相交区间的第一个最大序列是{(2, 7), (3, 6), (4, 8)},因为这些区间彼此相交,但第四个区间(7, 9)与第二个区间(3, 6)不相交,因此不包括在最大序列中。
让(l, r)成为当前I的最大前缀中所有区间的交点:在运行的例子中,它是(4, 6)。那么,(l, r)中的任何斜率都是I的该前缀中每个区间的ε-近似斜率。因此,我们在(l, r)中选择一个实数,并将其指定为该最大前缀中每个区间的斜率。然后继续确定其余区间的最大前缀,直到处理完整个序列I。
5 DISTRIBUTION-AWARE PGM-INDEX
定理1的PGM指数隐含地假设查询是均匀分布的,但这在实践中很少发生。例如,众所周知,搜索引擎中的查询遵循偏态分布,如Zipf法则[38]。在这种情况下,最好能有一个索引来回答最频繁的查询,比稀少的查询更快,从而实现更高的查询吞吐量[4]。以前的工作在二叉树[7]、Treaps[34]和跳过列表[5]的设计中利用了查询分布,这只是其中几个例子。
在这一节中,我们介绍了PGM-index的一个变体,**它不仅适应输入键的分布,也适应查询的分布。**这被证明是迄今为止第一个具有分布意识的学习型索引,其额外的积极特征是在空间上非常简明。
正式地说,给定一个序列S={(ki, pi)}i=1,…,n,其中pi是查询键ki的概率(假设是已知的),我们要解决分布感知字典问题,它要求一个数据结构在O(log(1/pi))时间内搜索到一个键ki,使平均查询时间与查询分布的熵H=P i=1,…,n pi log(1/pi)重合。
根据[28],引理1的算法可以修改为,给定平面上n个点中的每一个点的y范围,也可以找到在O(n)时间内相交于这些范围的所有(段)方向的集合。这对应于寻找最优的pla模型,其各个分段保证在给定的每个点的y范围内的近似值。因此,我们的关键思想是为每个键ki定义一个大小为yi = min {1/pi, ε}的y范围,然后将引理1的算法应用于该键集和y范围。显然,对于y范围为ε的键,我们可以使用定理1并推导出O(m)的相同空间界;而对于y范围为1/pi < ε的键,我们观察到这些键不超过ε(实际上,pi的和等于1),但它们可能分布在A的所有位置,因此在最坏的情况下它们会产生2个ε额外的段。因此,索引底层的总空间占用为Θ(m + ε),其中m为定理1中定义的值。现在,让我们假设对键ki的搜索到达了这个分布感知ppm索引的最后一层,因此我们知道在哪个段中搜索ki:在该段返回的ε-近似范围内的最后一个二分搜索步骤需要O(log min{1/pi, ε}) = O(log(1/pi)),正如我们的目标。
接下来,我们将展示如何以一种分布感知的方式,即在O(log(1/pi))时间内找到该段。我们进行类似于pgm索引的递归构造,但是由于分配给递归定义的键集的概率(以及变量y范围),因此要仔细设计递归步骤。
让我们考虑段s[a,b]覆盖键s[a,b] = {(ka, pa),…, (kb, pb)},用qa,b = maxi∈[a,b] pi表示S中某个键[a,b]的最大概率,用Pa,b = pb i=a pi表示S中所有键[a,b]的累积概率(这实际上是在搜索其中一个键时,最终出现在该段中的概率)。为了移动到pgm索引的下一个上层,我们创建了一组新的键,其中包括每个段s[a,b]覆盖的第一个键ka,并将其相关概率设置为qa,b/Pa,b。然后,我们将引理1算法应用于这个新的段集上,构造分布感知pgm索引的下一个上层。如果我们对这层新的“加权”段迭代上述分析,我们得出结论:如果我们从在这层以上执行的搜索中知道ki∈S[a,b],那么在这层中搜索ki的时间成本为O(log min{Pa,b/qa,b, ε}) = O(log(Pa,b/pi))。
让我们在另一个更高的层次上重复这个论证,以理解对搜索时间复杂度的影响。我们用S[a0,b0]⊃S[a,b]表示在这个上层包含ki的键的范围,即Pa0,b0的累积概率,并为第一个键ka0∈S[a0,b0]分配概率r/Pa0,b0,其中r是[a0,b0]中包含范围Pa,b形式的最大概率。换句话说,如果[a0, b0]被划分为{z1,…, zc},则r = maxi∈[1,c) Pzi,zi+1。正如前面所做的推理,如果我们从在以上级别上执行的搜索中知道ki∈S[a0,b0],那么在这一级别上搜索ki的时间成本是O(logmin {Pa0,b0/r, ε}) = O(log(Pa0,b0/Pa,b)),因为[a, b]根据定义,是[a0,b0]被划分的范围之一。
重复这样的设计,直到获得一个单独的段,我们得到在pgm索引的所有级别上搜索的总时间成本等于参数“抵消”(即伸缩和)的对数的和,并得到O(log(1/pi))。
6
对软件工程师来说,调整一个数据结构以符合应用的要求往往是一项困难和容易出错的任务,更不用说这些需求可能会因为数据分布、设备、资源要求等方面的突变而随时间变化。典型的方法是对要调整的数据结构的各种实例进行网格搜索,直到找到符合应用需求的实例。然而,并不是所有的数据结构都足够灵活,能够最好地适应这些要求,或者反过来说,搜索空间可能是如此巨大,以至于优化过程需要太多的时间[14, 20]。
在本节的其余部分,我们利用PGM-index的灵活设计来说明,它对底层应用的任何时空要求的调整可以通过一个优化策略有效地自动进行。(i)给定空间约束,输出最小化查询时间的PGM-指数;或者(ii)给定查询时间约束,输出最小化空间占用的PGM-指数。
The time-minimisation problem. 根据定理1,PGM索引的查询时间可以描述为t(ε) =δ (log2ε m) log(2ε/B),其中B是外部内存模型的页面大小,m是最后一级的段数,δ取决于内存的访问延迟。为了节省空间,我们引入sl(ε)来表示在PGM-索引的第l层可用的键上拥有精度ε所需的最小段数,并计算总段数为s(ε) = PL ‘=1 s’(ε)。根据Lemma 2,我们知道sL(ε)=m≤ n/(2ε),对于任何ε≥ 1,s’-1(ε)≤s’(ε)/(2ε)。因此,s(ε)≤PL’=0 m/(2ε)’ = (2εm- 1)/(2ε- 1)。
给定一个空间界限smax,"时间最小化问题 "包括最小化t(ε),条件是s(ε)≤smax。这里的主要挑战是,我们没有s(ε)的封闭公式,只有一个上限。第7.5节表明,在实践中,我们可以用一个简单的幂律来模拟m=sL(ε),其参数a和b是根据手头的数据集适当估计的。幂律涵盖了Lemma 2的悲观情况和数据集是严格线性的最佳情况。
显然,空间随ε的增加而减少,而查询时间t(ε)随ε的增加而增加,因为每一级执行二进制搜索的键的数量是2ε。因此,时间最小化的问题简化为找出当s(ε)=smax时候的ε值,因为它是我们能承受的最小的ε值。这样的ε值可以通过在有界区间E=[B/2, n/2]中进行二进制搜索来找到,这可以通过要求每个模型至少有一个页面大小的错误(即2ε≥B)来获得,因为较低的ε值不能节省I/O,同时观察到一个模型是最小的空间(即2ε≤n,由Lemma 2得出)。此外,只要我们的幂律近似成立,我们就可以通过猜测ε的下一个值而不是取当前搜索区间的中点来加速搜索 "最佳 "ε。事实上,我们可以找到s(ε)-smax的根,即s(εg)=smax的那个值εg。我们强调,这样的εg可能不是我们问题的解决方案,因为可能通过幂律的方式对s(ε)进行的近似或拟合并不精确。因此,可能需要更多的迭代搜索来找到最佳的ε。然而,我们保证通过逐步切换到二元搜索,总是比二元搜索快。确切地说,我们通过两者的简单凸组合将猜测εg偏向于当前搜索范围的中点εm。
7 EXPERIMENTS
我们在一台拥有2.3GHz英特尔至强黄金处理器和192GB内存的机器上实验了PGM-index的C++实现(可在github.com/gvinciguerra/PGMindex)。我们使用了以下三个标准数据集,每个数据集都有不同的数据分布、规律和模式。
- Web logs :包含了对网络服务器的约715M个请求的时间戳。
- Longitude :包含来自OpenStreetMap的约166M个兴趣点的经度坐标。
- IoT :包含了由安装在整个教学楼的物联网传感器记录的约2600万个事件的时间戳。
我们还根据区间[0, u]的均匀分布、指数为s的Zipf分布和标准差为σ的对数正态分布生成了一些合成数据集。
7.1 Space occupancy of the PGM-index
在这组实验中,我们估计了由我们的实现[39]返回的最佳PLA模型(见第2.1节)的大小,它提供了存储在PGM-索引底层的片段,并将其与FITing-tree[17]中使用的贪婪缩锥算法计算的非最佳PLA模型进行比较。这种比较很重要,因为PLA模型的大小是影响基于线性模型的学习索引的空间占用的主要因素。
表2显示,在109个钥匙的合成数据集上,改进(即段数的相对变化)从20%到75%不等。同样的表格也证实了真实世界数据集的这些趋势,在这些数据集上的改进幅度为30%到63%。为了完整起见,我们报告说,ε=8的最佳算法在2.59秒内为网络日志建立了一个PLA模型,而对于经度和物联网数据集,它只用了不到1秒。这意味着第2.1节的最优算法可以非常快速地扩展到更大的数据集。
由于很难证明输入键的数量和ε-近似段的数量之间的数学关系(除了我们在Lemma 2中证明的相当宽松的约束),我们对这种关系进行了经验调查,因为它量化了学习索引相对于传统索引的空间改进。图3显示,即使当ε小到8时,段的(最小)数量m也比原始数据集的大小n至少小两个数量级。
7.2 Query performance of the PGM-index
我们在Weblog数据集上评估了PGM-index和其他索引数据结构的查询性能,这是我们现有的最大和最复杂的数据集(见表2)。我们放弃了与FITing-tree的比较,因为PGM-index在结构上有明显的优势,而且它的索引在底层有最佳(最小)的段数。尽管如此,我们还是调查了PGM-指数的一些变体的性能,以便清楚地了解与基于多路搜索树(à la FITing-tree)、CSS-tree[33]或B±tree的经典方法相比,其递归索引所带来的改进。
在这个实验中,数据集被加载到内存中,作为一个连续的整数数组,用8字节和128字节的有效载荷表示。斜率和截距被存储为双精度的浮点数。每个索引都有10M个随机生成的查询。接下来的三段分别介绍了PGM-索引的三种索引策略的查询性能,PGM-索引与传统索引的比较,以及PGM-索引与RMI[22]在该实验场景下的比较。
PGM-index variants.为PGM-index实验的三种索引策略是二进制搜索、多路树(具体来说,我们实现了CSS-树)和我们新颖的递归结构(见2.2节)。我们分别用PGM◦BIN、PGM◦CSS和PGM◦REC来指代它们。除了PGM◦REC的最后一层之外,我们为所有的层设置了ε’=4,也就是包括在输入数据集上构建的片段。同样,为了与PGM◦REC进行公平的比较,CSS树的节点大小被设置为B=2ε’。图4显示,对于ε≤256的情况,PGM◦REC在PGM◦CSS中占优势,并且比PGM◦BIN有更好的查询性能。PGM◦REC相对于PGM◦CSS的优势在索引高度方面也很明显,因为前者有五层,而后者有七层,因此PGM◦REC的遍历时间更短,这是由更高的分支因子引起的(正如第2.2节所猜想的)。对于ε>256的情况,这三种策略的表现都差不多,因为所有的索引都很小,适合在二级缓存中使用。
PGM-index vs traditional indexes. 我们将PGM-index与高速缓存的CSS-tree和B±tree进行了比较。对于前者,我们使用了我们的实现。对于后者,我们选择了一个著名的库。
如图5所示,在页面大小为4-16 KiB的情况下,PGM-索引在这些传统索引中占主导地位。更小的页面大小的性能与主图范围相差太远(即更差),因此没有显示。例如,我们机器上最快的CSS-树的页面大小为128字节,占用了341 MiB,在查询性能上被PGM◦REC(ε=128)匹配,它只占用了4 MiB(82.7倍的空间)。另一个例子,最快的B+树的页面大小为256字节,占用874 MiB,在查询性能上被ε=4096的PGM◦REC匹配,占用87 KiB(四个数量级的空间)。
在这些图中,令人惊讶的是PGM指数在空间占用方面的改进,与B+树相比,PGM指数改进了四个数量级,与CSS树相比改进了两个数量级。正如第1节所述,传统的索引对数据的分布是盲目的,它们错过了数据趋势所提供的压缩机会。相反,PGM索引能够通过其最佳PLA模型适应数据分布,从而发现以前未知的时空权衡。为了完整起见,我们报告说,在90.6GiB的密钥-负载对中,最快的CSS-树需要1.2秒的时间来构建,而PGM-指数在82.7倍更少的空间内与它的性能相匹配,只需要0.9秒(尽管使用单线程和非优化的PLA模型计算)。
PGM-index vs known learned indexes. 图4和表2显示PGM指数改善了FITing树(也见本节开头的讨论)。在这里,我们完成了与其他已知的学习指数的比较:即2阶段的RMI,它在两个阶段使用了线性模型的组合。图5显示PGM指数在RMI中占优势,它确实有更好的延迟保证,因为它不是事先固定结构,事后检查错误,而是动态地、最优化地适应输入数据分布,同时保证所需的ε近似值,并使用尽可能少的空间。最有说服力的证据是近似位置和预测位置之间的平均绝对误差(MAE),例如,ε=512的PGM-index需要大约32K段,MAE为226±139,而具有相同数量的第二阶段模型(即最后一级的模型数量)的RMI的MAE为892±3729(多3.9×±26.8×)。这意味着RMI在查询执行中经历了更高和更难预测的延迟。我们报告说,最快的RMI需要30.4秒来构建,而PGM-index只需要2.1秒(少14.5倍)。
Discussion. 总的来说,实验表明PGM-index的构建速度很快(对一个91GiB的、有715M个键值对的真实表进行索引的时间不到3秒),而且其空间占用比最先进的FITing-tree低75%。此外,PGM索引在空间和时间上都超过了传统的和其他学习的索引结构(例如RMI)。特别是,它将CSS树的空间占用率提高了82.7倍,将B+树的空间占用率提高了四个数量级,同时实现了相同甚至更好的查询效率。
7.3 Dynamic PGM-index
为了实验插入和删除,我们从u(0, 1012)中生成了一个由109个独特的8字节 key组成的数据集,并为每个键关联一个8字节value。我们模拟了一个动态场景,生成了一批随机的10M操作,其中一部分是查询,其余的部分在插入和删除之间平均分配。所有的插入都是新键。对于查询和删除,其中一半是指数据集中的键,另一半是指新插入的项目。与我们在第7.2节所做的类似,我们从批次中随机挑选下一个操作,而不是按顺序处理批次。这就避免了不现实的情况,即所有的操作都是事先知道的,处理器投机性地执行批次中的后续操作。我们将PGM-索引的ε固定为64,并与B+树进行比较(因为RMI和CSS树都不支持插入和删除)。
图6显示,动态PGM索引在绝大多数的查询频率中,比B+树的延迟提高了13-71%。唯一比表现最好的B+树(即有512字节页面的树)慢的查询频率是0.8(慢1.0%)和0.9(慢15.2%)。总的来说,注意到两种数据结构的延迟趋势是很有意思的。一方面,在写量大的工作负载中,动态PGM-索引更好,而B+树则要付出节点拆分和合并的代价。另一方面,在重读工作负载中,B+树受这些节点操作的影响较小,达到了与动态PGM-索引相似的性能,甚至更好。这种延迟趋势的唯一例外是发生在仅有的一批查询中,在这批查询中,动态PGM-索引优于B±树,因为它相当于大量输入数据上的静态PGM-索引。
最后,我们报告说,在11个查询频率中,动态PGM索引平均占用1.38 MiB,而具有128、256、512和1024字节页面的B+树分别占用5.26 GiB(3890.8倍)、2.77 GiB(2050.6倍)、1.54 GiB(1140.2倍)和0.83 GiB(611.1倍)。
7.4 Compressed PGM-index
我们调查了第4节中提出的压缩技术的有效性。表3显示,坡度压缩算法大大减少了不同坡度的数量,达到了99.94%,同时仍然保留了相同的最佳段数。就空间占用而言,仅考虑PGM指数的最后一级,即最大的一级,压缩算法引起的减少达到了81.2%,如图7所示。请注意,在ε≥29的经度数据集中,斜率压缩不够有效。因此,从分段到斜率表的映射造成的开销超过了分段的原始空间占用。显然,在这种情况下,真实世界的应用会关闭坡度压缩。
之后,我们测量了压缩PGM指数的查询性能,在该指数中,对所有级别的段的截距和斜率进行了压缩。表4显示,与相应的PGM指数相比,空间占用减少了52.2%,但查询速度却适度降低(不超过24.5%)。
7.5
我们对多标准PGM-指数的实现以两种模式运行:时间最小化模式(简称min-time)和空间最小化模式(简称minspace),它们实现了第6节中描述的算法。在最小时间模式下,程序的输入是smax和对解决方案的空间占用的容忍度tol,输出是保证空间界限smax±tol的误差ε值。在最小空间模式下,程序的输入是tmax和对解决方案的查询时间的容忍度tol,输出是误差ε的值,保证查询操作的时间界限tmax±tol。我们注意到,引入容忍度参数使我们能够在任何进一步的步骤都不会明显改善解决方案时提前停止搜索(即,我们只寻求几个字节或纳秒的改善)。因此,tol不是一个必须调整的参数,而是一个像迭代方法中使用的停止标准。
为了建立PGM指数的空间占用模型,我们根据经验研究了形成最佳PLA模型的段数mopt=sL(ε)的行为,方法是改变ε并在我们的真实世界数据集上事先计算出的大约200个点(ε,sL(ε))上拟合90种不同的函数。从拟合结果来看,我们选择了用aε-b形式的幂律来模拟sL(ε)。作为进一步的设计选择,我们指出。(i) 幂律的拟合采用Levenberg-Marquardt算法,而寻根则采用牛顿方法;(ii) ε的搜索空间被设置为E=[8, n/2](因为一个缓存行可容纳8个64位整数);最后(iii) 猜测次数被设置为2dlog log Ee。
下面的实验是通过处理一些用例来执行的,以显示多标准PGM-指数的功效和效率。
Experiments with the min-time mode. 假设一个数据库管理员想为网络日志数据集寻找最有效的PGM索引,以适应1 MiB的二级缓存。我们的求解器通过设置ε=393,在19秒内进行10次迭代,得出了一个具有最小查询延迟和空间约束的PGM-索引。这个结果是通过用幂律46032135-ε-1.16近似sL(ε)得到的,保证了在ε∈[8, 1024]的范围内平均平方误差不超过4.8%。
作为另一个例子,假设一个数据库管理员希望为Longitude数据集找到最有效的PGM索引,以适应32KiB的L1缓存。我们的求解器通过设置ε=1050,在9秒内进行14次迭代,得出了一个具有最小查询延迟和空间约束的PGM索引。
Experiments with the min-space mode. 假设数据库管理员希望物联网数据集的PGM-索引具有最低的空间占用,能够在500 ns以内回答任何查询。我们的求解器通过设置ε=432,占用74.55KiB的空间,花费9次迭代和6秒的时间,得出一个符合该时间限制的最佳PGM-索引。
作为另一个例子,假设数据库管理员希望网络日志数据集的最压缩PGM索引能够在800 ns以内回答任何查询。我们的求解器通过设置ε=1217,占用280.05KiB的空间,花费8次迭代和17秒的时间,得出一个符合该时间限制的最佳PGM-索引。
Discussion. 与FITing-tree和RMI相比,Multicriteria PGM-index可以有效地交换查询时间和空间占有率,使其成为具有快速变化的数据分布和空间/时间限制的应用的一个有前途的方法。总的来说,在这两种模式下,我们的方法运行时间不到20秒。
8. CONCLUSIONS AND FUTURE WORK
我们介绍了PGM-index,这是一种针对全动态可索引字典问题的学习型数据结构,它可以将传统和现代学习型索引的查询/更新性能和空间占有率提高到几个数量级。我们还设计了PGM-index的三种变体:一种是利用特别的压缩技术改善其已经很简洁的空间占用,一种是适应查询分布,还有一种是在用户给定的空间占用或查询时间的约束下有效地优化自己。
我们将分布感知PGM指数的实施和实验以及对输入键和所产生的指数的空间占有率之间的映射的研究作为未来的工作(除了理论上的重要性,这将提高我们多标准PGM指数的性能)。其他的机会包括将PGM-index整合到一个真正的DBMS中并进行实验,特别是在外部内存的情况下,以及研究其他的实现方式(例如在搜索/更新算法中使用SIMD指令)。