2012-05-04 38 views
9

我有一個表布拉赫(緯度浮子,浮子經度,CREATE_TIME日期,owner_id INT,.....)用於範圍查詢條件的Oracle綜合指數

和我的代碼執行僅一個單一的查詢

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是從程序來動態PARAMS)

我的問題是應該建立什麼樣的指標;綜合指數? 如果是複合索引,我應該先放哪一列? 這個指數有多有效?

我想了很久,並且找不到關於oracle索引如何工作的詳細文檔。

我可以找到它使用B-樹實現的文檔,在我們的例子中:B-樹中的每個鍵都是一個4元組(column1,column2,column3,column4),其中這些元組的排序關係是定義爲詞彙順序。

然後上面的查詢,假設我們的訂單(owner_id,CREATE_TIME,經度,緯度),我想 甲骨文將首先需要二進制搜索的點(01,T1,L1,LL1),此操作,該指數確實有用。但是接下來,我們需要找到這個第一個插入點的終點:我們需要找到(o1,t1,l1,ll2),這也可以通過二分搜索來完成。

接下來,我們需要找到滿足條件的下一節,所以我們需要 find(o1,t1,lx,ll1)其中lx是大於l1的下一個值,我們可以通過二分查找太。 但在我們的情況下,很可能在同一緯度上,經度不能超過1,因此這裏的二分查找並不比線性掃描更有效。

遵循這種精神,似乎我們應該首先將一個小範圍的基數列, 在這種情況下,create_time,如果我們的點是在幾天內創建的。 也如果我們從來沒有做範圍條件,但只有等於(=)的條件,那麼哪個列是第一個,沒關係?

,以使其更清晰,這裏是一個簡單的例子:

讓我們說我有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),所以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樹遍歷需要 定位(78-34-1)間隔,因此(78-34-1)* 2查找(1爲開頭 一個爲結束位置),而不僅僅是2查找。

所以,如果我們有更高的維度,間隔計數成倍增加 與維數,所以索引可能沒有用處了------ 這是我所關注

非常感謝 陽

回答

9

如果您唯一的目標是創建一個索引來優化此查詢,那麼您最好先選擇具有最高選擇性的列的組合索引中的列。如果latitude上的謂詞排除比其他謂詞多得多的行,則首先使用該列將會更有效。如果owner_id上的謂詞排除比其他謂詞多得多的行,則首先使用該列會更有效。

但實際上,我們很少創建索引,其唯一目的是優化單個查詢。通常,爲了使索引維護的開銷值得,我們希望我們的索引在許多查詢中都有用。在組合索引的情況下,這意味着按查詢在該列上具有謂詞的概率對列進行排序。例如,如果您在owner_id, create_time, latitude, longitude上有複合索引,則可以將其用於僅在owner_id上指定謂詞的查詢。但是您不會真實地使用該索引來查詢指定謂詞longitude的查詢。

3

首先,請記住,「B-Tree」中的「B」不是「二元」。

其次,當涉及到Oracle的索引,你也有一個位圖索引的選擇,如果:

  1. 您有一個企業版許可證
  2. 你沒有太多的會議同時修改表
  3. 你的索引值不接近是唯一的(陳述,位圖索引只適用於低基數列一般都是誇張的使用)

一位圖索引擅長的查詢類型有效地將多個列上的謂詞組合在一起,特別是當謂詞列集合發生變化時(當然可能不是這種情況)。如果滿足上述三個條件,那麼值得測試一下在表上有四個單獨的位圖索引的效果。

+0

謝謝,但現在我只關心B樹索引的問題;儘管在實踐中Oracle可能會使用位圖索引,正如您所指出的那樣 –

0

此表是用於OLTP還是作爲DWH? 如果在此表上沒有許多單行/多線程DML語句,則可以使用位圖索引。 位圖索引允許你在多個索引(又名星型變換)之間運行ROWID AND運算符。爲了做到這一點,在每一列上創建一個位圖索引。 就像我說過的,這個解決方案最適合DWH系統,在那裏你有一個批量插入。

0

多維範圍查詢是最好的處理,恕我直言,在標準的B-tree索引之外。關於一般主題的一些論文可以通過關於「多維範圍查詢」的網頁搜索找到。

Oracle提供了一種名爲Oracle Spatial的產品。本產品的文檔包括Chapter 4中有關創建空間索引和執行查詢的示例和解釋。沒有新的SQL語法;他們創建索引的示例是:

CREATE INDEX territory_idx ON territories (territory_geom) 
    INDEXTYPE IS MDSYS.SPATIAL_INDEX; 

它創建一個R樹索引。

我認爲R-trees,kdb-trees和類似空間結構的存在是事實的證據,標準B-tree可能不適合這些類型的應用程序。

1

一個容易的蠻力解決方案是在同一個表上創建多個索引組合,運行EXPLAIN PLAN打開的查詢,然後選擇您的DBMS喜歡使用的索引。