我有一张桌子 Blah(纬度浮动,经度浮动,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 中的每个键都是一个 4 元组:(column1,column2,column3,column4)其中这些元组的排序关系被定义为词法命令。
那么对于上面的查询,假设我们的顺序是(owner_id, create_time, latitude, longitude),我猜oracle首先需要对点(o1, t1, l1,ll1)进行二分查找,对于这个操作,索引确实是有用。但是接下来,我们需要找到第一个中间体的终点:我们需要找到 (o1,t1, l1, ll2 ),这也可以通过二分查找来完成。
接下来,我们需要找到满足条件的下一个部分,因此我们需要找到 (o1, t1, lx, ll1 ),其中 lx 是下一个大于 l1 的值,我们也可以通过二分查找找到它。但是在我们的例子中,很可能对于相同的纬度,经度不能超过 1 个,所以这里的二分查找并不比线性扫描更有效。
遵循这种精神,如果我们的积分仅在几天内创建,我们似乎应该将具有较小值范围基数的列放在第一位,在这种情况下,create_time。同样,如果我们从不做范围条件,而只做等于(=)条件,那么哪一列在前并不重要,对吧?
为了更清楚,这里有一个更简单的例子:
假设我有 2 列,X 和 Y
在数据库中,两者的值都是 [1,2,....100],所以我们有 100x100 行
我的查询是
select * from mytable where X > 34 and X < 78 and Y > 12 and Y < 15;
假设我们的索引在 (X, Y) 上,所以 2 个值之间的比较规则是
v1 < v2 <=====> v1.x < v2.x || v1.x == v2.x && v1.y < v2.y
给定上述排序规则,我们可以看到索引中的值是按顺序排列的(x,y 的值):
1,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 次查找。
因此,如果我们有更高的维度,则间隔计数会随着维度的数量呈指数增长,因此索引可能不再有用 ------ 这是我关心的问题
非常感谢杨