我的問題是數據庫如何存儲數據以及它如何在內部執行查詢。數據庫如何在B-Tree/B + Tree內部存儲數據
假設我們有以下在我們的表中的字段:
- ID
- 名稱
- 年齡
- 重量
- 經理
,我們查詢select * from Table1 where age>50 and weight<100
我只是好奇它如何執行內部查詢。
在這個例子中,B-Tre/B + Tree的節點包含什麼?
我的問題是數據庫如何存儲數據以及它如何在內部執行查詢。數據庫如何在B-Tree/B + Tree內部存儲數據
假設我們有以下在我們的表中的字段:
,我們查詢select * from Table1 where age>50 and weight<100
我只是好奇它如何執行內部查詢。
在這個例子中,B-Tre/B + Tree的節點包含什麼?
您選擇的示例是單個樹無法完成這項工作的少數情況之一(兩個獨立的範圍)。
然而,我的工作正在進行中電子書的第一章介紹了B樹索引的內部運作:http://use-the-index-luke.com/anatomy/
編輯瞭解詳情爲什麼兩個指標可能是上面的例子有用。
上面的查詢可以通過三種可能的索引配置來支持:
上AGE
級聯索引,然後WEIGHT
(以該順序)。
如果查詢會讀取所有記錄WHERE AGE > 50
,然後按WEIGHT
進行過濾。
連接索引WEIGHT
然後AGE
(其他順序)。
這種方式不同:讀取所有記錄WHERE WEIGHT < 100
,然後通過AGE
進行過濾。
什麼是更有效率取決於您擁有的數據。如果有更少的記錄AGE > 50
比WEIGHT < 100
第一個會更有效率,否則第二個。但是,如果您使用不同的值查詢,則圖片可能會更改。
串聯索引不能很好地支持查詢的原因是每個索引順序只在一個軸上。每個索引條目都在另一個之前或之後,但從不在其旁邊。所有索引條目構建一個鏈。
具有兩個獨立範圍查詢的查詢將需要兩個軸,不像鏈,但更像是一個棋盤。一個軸爲AGE
另一個爲WEIGHT
。如果可以的話,你的查詢只需要掃描棋盤的一個角落。
但是,b樹只有一個座標軸,因此您必須首先選擇使用哪個標準。如果您選擇AGE
這意味着從AGE 50
開始,整個鏈將被掃描直到結束。只有部分存儲在鏈條邊上的記錄也有資格獲得WEIGHT < 100
,其他記錄必須讀取,但將被丟棄。
因此,一個長長的故事來解釋爲什麼一棵樹不能支持具有兩個獨立範圍子句的查詢。在另一方面,一個連結指數可以執行以下操作相當不錯:
WHERE age = 50 AND weight < 100
WHERE weight = 100 AND age > 50
WHERE age > 50 AND age < 70;
但是,如果有兩個不等式運營商在兩個不同列中使用的問題出現了。
那麼,該怎麼辦?
第三種可能的方法是在兩列上有兩個獨立的索引。這可以讓你擁有儘可能多的座標軸(只需創建更多的索引)。但是,有幾個龐大的問題。首先,並非所有的數據庫產品都支持這一點。只要它得到支持,這是一個相當廣泛的操作。它通常用於掃描每個索引的方式,爲每個結果構建一個位圖索引。這些位圖索引然後被加入以應用AND
運算符。這就是大量的數據管理 - 如果每個條件對於自己的條件都不是非常有選擇性的,那麼只需付出努力,但是兩者都是非常有選擇性的。
請問我的建議?
如果您的查詢在OLTP環境中運行:請使用一個連接索引。 兩個獨立的索引只是最後一招的選項。但是,如果您在OLAP環境中工作,則可能無論如何都需要位圖索引。
PS: 索引AGE
是在我的書(與解決方案)的exercise - 尤其是因爲存儲AGE
是一種不好的做法,你應該存儲誕生之日起代替。
嗨,馬庫斯,我已經通過你的工作進行中的電子書的鏈接。你已經非常清楚地解釋了這些事情,很好的工作。我知道索引是如何存儲在內部的,但作爲我原來的問題,我們是否需要兩種索引來處理這種類型的範圍查詢? – ZeNo 2010-10-31 05:36:51
嗨,我猜這個盒子對於我的回答來說太少了,所以我已經編輯了上面的'一點點'。 – 2010-10-31 06:47:29
非常感謝Markus對這種簡潔的解釋。我現在覺得開明:) – ZeNo 2010-10-31 10:59:45