Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于索引列在Oracle SQL中查找“下25行”_Sql_Oracle_Performance_Query Optimization - Fatal编程技术网

基于索引列在Oracle SQL中查找“下25行”

基于索引列在Oracle SQL中查找“下25行”,sql,oracle,performance,query-optimization,Sql,Oracle,Performance,Query Optimization,我有一个大表~200M行,在数字列Z上建立索引。在键列K上也有索引 K Z = ========================================== 1 0.6508784068583483336644518457703156855132 2 0.4078768075307567089075462518978907890789 3 0.5365440453204830852096396398565048002638 4 0.757328157325778235285

我有一个大表~200M行,在数字列Z上建立索引。在键列K上也有索引

K  Z
=  ========================================== 
1  0.6508784068583483336644518457703156855132
2  0.4078768075307567089075462518978907890789
3  0.5365440453204830852096396398565048002638
4  0.7573281573257782352853823856682368153782
我需要做的是找到给定记录周围的25条记录。例如,从K=3开始的下一条记录将是K=1,然后是K=4

我得到了几个消息来源的支持,最明显的是来自佛罗里达州立大学的一些人,他们认为下面的SQL应该可以工作。不难想象,沿着索引列以升序或降序进行扫描将是有效的

select * from (
  select *
  from T
  where Z >= [origin's Z value]
  order by Z asc
) where rownum <= 25;
理论上,这应该可以找到接下来的25行,类似的变化也可以找到前面的25行。但是,这可能需要几分钟,并且解释计划始终包含完整的表扫描。完全表扫描对我来说太昂贵了,但我所做的似乎都没有提示查询优化器利用索引,当然,将上面的>=改为等号,这表示索引存在且可操作。我已经尝试了几个提示,但都没有用,索引,在几个排列中

我想做的事不可能吗?如果我试图在一个我有更多控制权的大型数据结构上执行此操作,我会在索引列的值和树上构建一个链表以找到正确的入口点。然后遍历列表将非常便宜是的,我可能需要在整个磁盘上运行以查找我正在查找的记录,但我肯定不需要扫描整个表


我将添加一个实例,以防我使用的数据库正在运行Oracle database 11g Enterprise Edition 11.2.0.3.0-64位版本,这对我的查询很重要。

我构建了一个包含10K行的小测试用例。当我填充表时,Z值已经排序,您给出的确切查询倾向于使用索引。但是,当我用随机值填充它,并刷新表统计数据时,它开始进行全表扫描,至少对一些大于25的n值进行扫描。因此,优化器会在一个临界点上决定查找索引项然后在表中找到相应行所需的工作量大于进行完整扫描所需的工作量。当然,它的估计可能是错误的,但这就是它必须继续下去的原因

我注意到您使用的是SELECT*,这意味着查询同时返回两列。这意味着必须访问实际的表行,因为两个索引都不包含两个列。这可能会促使优化器倾向于对较大样本进行完整表扫描。如果查询可以仅从索引中完成,则更有可能使用索引

一种可能性是您根本不需要返回K的值。如果是这样,我建议您将SELECT*的两个匹配项都更改为SELECT z。在我的测试中,此更改导致一个执行完整表扫描的查询改为使用索引扫描,而根本不访问表本身


如果您确实需要在结果中包含K,那么您可以尝试在Z,K上创建一个索引。此索引可用于满足查询而无需访问表。

请澄清。如果您的表有200行,则1。。200,如果您想要最接近第100行的25,您将得到第88行。。112 ? 同样的情况。离第5行最近的25行将是第1行。。25?不确定它在速度方面是否更好,但尝试一下……如果我理解的话,在12行之前和13行之后按k行排序correctly@JuanCarlosOropeza抱歉,我不太清楚边缘案例或实际感兴趣的范围。我实际上需要的是两个方向上最近的25条记录。在表格的开头和结尾,我并不太担心一个方向的短缺。数字25也不是一成不变的,但主要是为了调味。我想解决这个问题的解决方案将适用于不同的范围。@Mihai我没有听说过介于。。。前面和。。。下面是语法,但我一定会尝试一下。它是否适用于与磁盘上的行顺序不同的顺序?您可以按任何需要进行排序