2011-06-20 18 views
1

對不起,如果標題混淆,我很難清楚地說出我的問題。Oracle SQL:通過使用非唯一索引返回的子集中的行是否也可以通過使用第二個非唯一索引來查詢?

這是我的場景: 我有一個名爲SUBSCRIBERS的表,它有兩個非唯一索引。索引的列是AREA_ID和SUBSCRIPTION_DATE。

現在,我想(高效地)查詢特定區域中訂閱了特定日期後的所有訂閱者。例如SQL:

SELECT * 
FROM subscribers 
WHERE area_id = 'areaID' 
AND subscription_date > to_date(some_date) 

所以我們說要執行這個查詢,Oracle首先抓住所有的行給定areaID表示,讓我們說,這仍然是一個非常大的行數。 Oracle能夠按訂閱日期對這一行的子集進行範圍掃描嗎?或者,非唯一subscription_date索引僅適用於FULL表,這意味着Oracle必須對子集進行線性掃描?

另外,我不確定技術上的短語是如何描述也適用於子集的集合的索引。如果有人知道正確的術語,這將是一個很酷的獎金。

+0

你有蟾蜍嗎?如果是的話,看看執行計劃,它會引導你完成對這個查詢的操作。 –

+1

不需要toad,只需使用解釋計劃:http://download.oracle.com/docs/cd/B10500_01/server.920/a96533/ex_plan.htm –

+0

@kingjiv,認爲它可能可用我只是_know_它是在蟾蜍 –

回答

4

根據Oracle版本,可能會使用兩個索引。但是,爲了做到這一點,Oracle必須將兩個b-tree索引轉換爲位圖索引,並在兩者上進行位圖合併。這不是一個特別有效的操作,所以它通常不是你想要的查詢計劃。

Oracle b-tree索引通過將密鑰和ROWID存儲在密鑰出現的表中來工作。爲了組合這些索引,Oracle首先將它們轉換爲位圖索引,該索引本質上是一個二維數組,用於指示哪一行滿足哪些條件。然後它可以相對容易地組合兩個位圖索引。此操作的複雜性在於將b-tree索引初始轉換爲位圖索引。原則上,沒有什麼能阻止Oracle實現一個查詢計劃,該計劃從兩個索引中獲取所有ROWID並執行這兩個集合的交集。不過,我認爲位圖轉換路徑通常效率更高,因爲這是Oracle實施的。

Jonathan Lewis在他的書「基於成本的Oracle基礎知識」中有關於bitmap conversions的章節。

在(AREA_ID,SUBSCRIPTION_DATE)上設置組合索引幾乎肯定會更高效。這將允許您對單個複合索引執行索引範圍掃描。只有在AREA_ID上有謂詞的查詢才能夠使用此複合索引,因此AREA_ID上的索引通常會變成冗餘。

+0

非常有趣的賈斯汀,謝謝你,我絕對計劃使用複合索引。但出於好奇,你能指引我解釋第一段的細節嗎?我想深入研究索引的機制,並且仍然對爲什麼多個非唯一B樹索引不能同時在同一個查詢中使用感興趣。 –

+0

@simmbot - 我擴展了第一段。 –

+1

@simmbot希望這個鏈接有助於理解問題:http://use-the-index-luke.com/sql/where-clause/searching-for-ranges/index-combine-performance –

1

爲了完整起見,我想從馬庫斯Winand的網站,這直觀地解釋了爲什麼多個不同的B樹索引不能同時由查詢引擎使用發佈此摘錄:

...具有一個軸 的鏈條支持一個範圍條件作爲訪問謂詞。支持兩個 作爲訪問謂詞的範圍條件將意味着掃描棋盤上的一個角落 。但是,B樹索引是一個鏈 - 沒有第二個軸。

來源:http://use-the-index-luke.com/sql/where-clause/searching-for-ranges/index-merge-performance

而且有用的圖表:http://use-the-index-luke.com/sql/anatomy/the-tree

換句話說,B樹索引只構建基於一個數據字段排序的樹。索引的節點是n元組,但是索引的是1元組。

看起來好像是用第二個b-tree索引查詢一個b-tree索引返回的子集,第一個b-樹索引的條目需要另外存儲對第二個b中每一行位置的引用樹索引。但是,我不確定這是否會起作用,因爲b-tree索引是基於的值而不是位置 - 它們不是random access數據結構。

不確定乍一看這會引入什麼複雜性,但我相信這將是一個多索引的噩夢。您需要一種機制來添加額外的索引位置引用(每個額外的索引會將索引中的條目從n元組轉換爲(n + 1)-tuples),您需要一種機制來對其他索引應用過濾器跳過未引用的位置,並且在創建/更新/刪除操作時,您需要一種機制來跨索引同步引用。

相關問題