我读到某个地方,当你有一个倒排索引时(例如,你有一个排序的brutus页面列表,一个caesar页面的排序列表,以及一个排序的calpurnia页面列表),当你做caesar AND时brutus和calpurnia,如果calpurnia和brutus的页数小于caesar的页数,那么你应该做caesar AND(brutus和calpurnia),这意味着你应该首先评估后者和。通常,只要您有一系列AND,就始终首先评估具有最少页数的对。这背后的原因是什么?为什么效率这么高?
答案 0 :(得分:0)
对于每个倒排索引的情况都不是这样。如果您需要按顺序扫描整个反向索引,那么无论您首先执行哪个过帐列表交叉都无关紧要。
但是,假设倒置列表存储在索引关系中的情况。然后,评估具有较少数量的文档出现的对将等于具有较高选择性的连接关系,从而提高评估的效率。
直观地说,当我们将较小的列表相交时,我们会创建一个更强的过滤器,用作索引的提要以查找匹配项。
假设我们有兴趣评估关键字查询a b c
,其中a
,b
和c
是文档中的文字。还假设匹配的文档数量如下:
a --> 20
b --> 100
c --> 1000
a+b --> 10
a+c --> 15
b+c --> 50
a+b+c --> 5
请注意,(a JOIN b)
的尺寸为10
而(b JOIN c)
的尺寸为50
。因此,第一个需要10
访问c
上的索引,而第二个需要50
访问a
上的索引。但是使用基于散列或基于树的索引,对索引的这种访问在成本上没有太大差别,通常在单个I / O中完成。
答案 1 :(得分:0)
要认识到的重要一点是,由于您已经提到的排序,对于任何给定的文档ID,反转列表可以搜索非常有效(通常,在对数时间),例如使用二分搜索。
要查看其效果,请假设查询caesar AND brutus
,并假设caesar
和occ brutus 有occ caesar 页面brutus
的页面(即occ X 表示术语X的页面列表的长度)。现在假设,为了示例,occ caesar > occ brutus ,即caesar
在内容中出现的频率高于brutus
。
您要做的是迭代遍历brutus
首先的所有网页,并搜索 caesar
的网页列表。如果确实可以在对数时间内搜索列表,则表示您需要
occ brutus * log(occ caesar )
识别包含两个术语的所有页面的计算步骤。
如果您反向完成(即遍历caesar
列表并在brutus
列表中搜索其中的每个页面),则较小的数字将会结束在对数中,更大的数字将成为一个因素,因此评估所花费的总时间会更长。
说到这一点,同样重要的是要意识到在实践中事情比这更复杂,因为(a)列表不仅被排序而且被压缩,这使搜索更难,(b)部分列表可能存储在磁盘上而不是存储器中,这意味着磁盘访问的总数绝对比计算步骤的总数更重要。因此,上述算法可能不适用于其最纯粹的形式,但原理如上所述。