微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Oracle复合索引用于范围查询条件

我有一个表Blah(纬度float,经度float,create_time date,owner_id int,…..)

我的代码只能执行一次查询

select * 
from Blah 
where latitude < l1 and latitude > l2   
and longitude < ll1 and longitude > ll2   
and create_time < t1 and create_time > t2 
and owner_id < o1 and owner_id > o2 ;

(当然,值l1,l2,… o1,o2是来自程序的动态参数)

我的问题是我应该创建什么样的索引?综合指数?
在复合指数的情况下,我应该先列哪一列?
指数有多好?

我想了很久,没有找到关于oracle索引如何工作的详细文档.

我可以使用B-tree找到使用B-tree实现的文档,在我们的例子中:B树中的每个键都是一个4元组:(column1,column2,column3,column4),其中这些元组的排序关系被定义为词法订购.

那么对于上面的查询,假设我们的订单是(owner_id,create_time,纬度,经度),我猜
oracle首先需要二进制搜索到点(o1,t1,l1,ll1),对于这个操作,索引确实是有用的.
但接下来,我们需要找到第一个中间件的终点:我们需要找到(o1,ll2),这也可以通过二进制搜索来完成.

接下来,我们需要找到满足条件的下一节,所以我们需要
find(o1,lx,ll1)其中lx是大于l1的下一个值,我们可以通过二进制搜索找到这个.
但在我们的情况下,很可能在同一个纬度上,可能不超过1个经度,
所以这里二进制搜索不比线性扫描更有效.

按照这种精神,看来我们应该把列的数值范围基数放在第一位,
在这种情况下,如果我们的分数仅在几天内创建.
如果我们从来没有做过范围条件,而只是等于(=)条件,那么第一列是什么呢?

为了更清楚,这里有一个更简单的例子:

假设我有2列X和Y

在db中,两者的值都是[1,2,… 100],所以我们有100×100行

我的查询

select * from mytable where X > 34 and X < 78 and Y > 12 and Y < 15;

说我们的索引是(X,Y),所以两个值之间的比较规则是

v1 < v2 <=====>  v1.x < v2.x || v1.x == v2.x && v1.y < v2.y

给定上述排序规则,我们可以看到索引中的值是
连续排列(x,y的值):

1,1,2 1,3 .... 1,100     
2,1  2,2 2,3 ......2,100
.....
100,1 100,2 ....... 100,100

现在,要查询查询中的值,需要B-Tree遍历
定位(78-34-1)间隔,因此(78-34-1)* 2查找(1开始
一个用于结束位置),而不仅仅是2个查找.

所以如果我们具有更高的维度,则间隔数量呈指数增长
与维数,所以索引可能不再有用了——
这是我的关注

非常感谢

如果您唯一的目标是创建一个索引来优化此查询,那么您最好首先使用最有选择性的列排序组合索引中的列.如果纬度上的谓词比其他谓词消除了更多的行,那么首先要使该列更有效.如果owner_id上的谓词比其他谓词消除了实质上更多的行,则首先将该列更有效.

实际上,我们很少创建索引,其唯一目的是优化单个查询.一般来说,为了使索引维护的开销值得,我们希望我们的索引在许多查询中都是有用的.在复合索引的情况下,这意味着按查询在该列上具有谓词的概率排序列.如果在owner_id,经度等上有一个复合索引,那么可以将其用于仅在owner_id上指定谓词的查询.但是,实际上,您不会将该索引用于仅在经度上指定谓词的查询.

原文地址:https://www.jb51.cc/oracle/204868.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐