【发布时间】:2015-12-01 21:01:28
【问题描述】:
我有一个大表(约 200M 行),它在数字列 Z 上建立索引。在键列 K 上也有一个索引。
K Z
= ==========================================
1 0.6508784068583483336644518457703156855132
2 0.4078768075307567089075462518978907890789
3 0.5365440453204830852096396398565048002638
4 0.7573281573257782352853823856682368153782
我需要做的是找到“围绕”给定记录的 25 条记录。例如,从 K=3 开始的“下一个”记录将是 K=1,然后是 K=4。
我得到了几个消息来源(最著名的是佛罗里达州立大学的一些人的this paper)的领导,认为像下面这样的 SQL 应该可以工作。不难想象,沿着索引列以升序或降序扫描会很有效。
select * from (
select *
from T
where Z >= [origin's Z value]
order by Z asc
) where rownum <= 25;
理论上,这应该找到 25 个“下一个”行,类似的变体可以找到 25 个“上一个”行。但是,这可能需要几分钟,并且解释计划始终包含全表扫描。全表扫描对于我的目的来说太昂贵了,但我所做的任何事情似乎都没有提示查询优化器利用索引(当然,简短地将上面的 ">=" 更改为等号,这表明该指数存在且可操作)。我尝试了几个提示都无济于事(索引,index_asc 在几个排列中)。
我想做的事是不可能的吗?如果我试图在我有更多控制权的大型数据结构上执行此操作,我会在索引列的值和树上构建一个链表以找到正确的入口点。然后遍历列表将非常便宜(是的,我可能必须在整个磁盘上运行才能找到我正在寻找的记录,但我肯定不必扫描整个表)。
如果我正在使用的数据库运行 Oracle Database 11g 企业版 11.2.0.3.0 - 64 位,这对我的查询很重要。
【问题讨论】:
-
要清楚。如果您的表有 200 行
1 .. 200并且您想要最接近行100的 25 行,您将获得行88 .. 112?同样的情况。那么最接近行5的 25 行将是行1 .. 25吗? -
不确定它的速度是否更好,但如果我理解正确,请尝试
...WHERE something ORDER BY k ROWS BETWEEN 12 PRECEDING AND 13 FOLLOWING -
@JuanCarlosOropeza 抱歉,我对边缘情况或实际感兴趣的范围不是很清楚。我真正需要的是任一方向上最接近的 25 条记录。在表格的开头和结尾,我不太担心一个方向或另一个方向的短缺。数字 25 也不是一成不变的,主要是为了调味。我认为解决问题的解决方案将适用于不同的范围。
-
@Mihai 我没有听说过 BETWEEN ... PRECEDING AND ... FOLLOWING 语法,但我一定会试一试。它是否适用于与磁盘上的行顺序不同的顺序?
-
您可以随意订购
标签: sql oracle performance query-optimization