ted*_*ddy 9 oracle indexing optimization composite-index
我有一张表Blah(纬度浮点数,经度浮点数,create_time日期,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,纬度,经度),我猜oracle首先需要二进制搜索到点(o1,t1,l1,ll1),对于这个操作,索引确实是有用.但接下来,我们需要找到第一个interium的终点:我们需要找到(o1,t1,l1,ll2),这也可以通过二分搜索来完成.
接下来,我们需要找到满足条件的下一部分,所以我们需要找到(o1,t1,lx,ll1)其中lx是大于l1的下一个值,我们也可以通过二分搜索找到它.但在我们的情况下,很可能对于相同的纬度,经度不会超过1,因此这里的二分搜索并不比线性扫描更有效.
遵循这种精神,似乎我们应该首先使用小值范围基数列,在本例中为create_time,如果我们的点仅在几天内创建.如果我们从不做范围条件,但只有等于(=)条件,那么哪个列是第一列并不重要,对吧?
为了更清楚,这是一个更简单的例子:
假设我有2列,X和Y.
在db中,两者的值都是[1,2,.... 100],所以我们有100x100行
我的疑问是
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, 1,2 1,3 .... 1,100     
2,1  2,2 2,3 ......2,100
.....
100,1 100,2 ....... 100,100
现在,要搜索查询中的值,B树遍历需要定位(78-34-1)间隔,因此(78-34-1)*2查找(1表示结束位置的开头) ,而不仅仅是2次查找.
因此,如果我们有更高的维度,间隔计数会随着维度的数量呈指数级增长,因此索引可能不再有用------这是我的关注点
非常感谢杨
如果您的唯一目标是创建一个索引来优化此查询,那么您希望首先使用最具选择性的列对复合索引中的列进行排序.如果谓词latitude消除了比其他谓词多得多的行,那么首先使该列更有效.如果谓词owner_id消除了比其他谓词多得多的行,那么首先使该列更有效.
但实际上,我们很少创建索引,其唯一目的是优化单个查询.通常,为了使索引维护的开销值得,我们希望索引在许多查询中都有用.在复合索引的情况下,这意味着按查询在该列上具有谓词的概率对列进行排序.owner_id, create_time, latitude, longitude例如,如果您有复合索引,则可以将其用于仅指定谓词的查询owner_id.但实际上,您不会将该索引用于仅指定谓词的查询longitude.
| 归档时间: | 
 | 
| 查看次数: | 2966 次 | 
| 最近记录: |