摘要:
堆表:又稱堆組織表,常用的表類型,以堆的方式管理,當增加數據時,將使用段中第一個適合數據大小的空閑空間。當刪除數據時,留下的空間允許以后的DML操作重用。 堆組織表(heap table)
應用中99%(或者更多)的情況下使用的可能都是堆組織表,不過隨著IOT的出現,這種狀況以后可能會有所改觀,因為IOT本身就可以加索引。執行 CREATE TABLE語句時,默認得到的表類型就是堆組織表。如果你想要任何其他類型的表結構,就需要在CREATE語句本身中指定它。
堆 (heap)是計算機科學領域中得到深入研究的一種經典數據結構。它實際上就是一個很大的空間、磁盤或內存區(當然,這里所說的磁盤是指數據庫表的相應磁 盤),會以一種顯然隨機的方式管理。數據會放在最合適的地方,而不是以某種特定順序來放置。許多人希望能按數據放入表中的順序從表中取出數據,但是對于 堆,這是無法保證的。這一點很容易說清楚。 參見:
oracle表類型? http://suntengjiao1.blog.163.com/blog/static/99211088200982522251123/
㈠ HOT和IOT的起源
堆組織表的存儲速度因為不用考慮排序, 所以存儲速度會比較快. 但是要查找符合某個條件的記錄, 就必須得讀取全部的記錄以便篩選.
而這個時候為了加快查詢速度, 索引就出現了, 索引是針對少量特定字段的值拿出來進行排序存儲, 并記錄在表中的位置,
而因為索引是有序的, 所以就會很容易通過索引查詢到具體的記錄位置, 然后再根據記錄位置直接從表中讀取該記錄.
同時因為索引的字段較少, 所以索引通常會比其基表小得多.
從上面通過索引訪問表記錄的方式可以看出, 當要訪問的數據量較大時, 通過每一條記錄的位置去訪問原始記錄,
每一條符合條件的記錄都需要經過索引訪問后再訪問基表這樣一個復雜的過程, 這會花費很多時間,
同樣, 如果不經過索引而直接查詢表, 也可能因為表字段太多, 記錄較大的情況下把全部的數據讀取進來, 這也會花費很多時間.
那怎么辦呢?
這個時候就會想到, 如果表中數據本身就是有序的, 這樣查詢表的時候就可以快速的找到符合條件的記錄位置,
而很容易判斷符合條件記錄的位置, 這樣只需要讀取一小部分數據出來就可以了, 不需要全表記錄都讀取出來進行判斷.
索引表就這樣產生了.當然索引表中插入,更新資料的時候可能會因為需要排序而將數據重組, 這時候數據插入或更新速度會比堆組織表慢一些.
如果堆組織表上有索引, 那么對堆組織表的插入也會因為要修改索引而變慢
我們可以看到堆組織表+索引的方式 與 索引表 都能夠實現數據的快速查找, 那為什么不全部采用索引表呢, 這樣不是很簡單嗎?
我能想到的是前者我們可以針對不同的查找條件建立多個索引, 而后者卻不行, 后者只能對某一組查詢條件有效.
當然了,索引表上查詢任何記錄都是走索引的, 因為它本身就是索引結構.
當查詢條件不符合指定條件時, 必須走 index full sacn , 需要掃描全部索引.
這就是說這時無法利用索引表已經根據某些字段排序的事實.也即排序對于這個查詢來說無用.
而符合指定的條件時就會走 index range scan
㈡ 定義
① 堆組織表,其索引中記錄了記錄所在位置的rowid,查找的時候先找索引,然后再根據索引rowid找到塊中的行數據。索引和表數據是分離的
② 索引組織表,其行數據以索引形式存放,因此找到索引,就等于找到了行數據。索引和數據是在一起的
㈢ 查找過程 ? ? ? ? ? ? ? ?① 堆組織表 ? ? ? ? ?? ? ? ? ? ? 一般索引大概3-5層,比如rowid為007,那么要找到007可能會先從第一層找<1000,再在第二層找到<100 ? ? ? ? ? 然后在第三層找到007(注意這已經是3次I/O) ? ? ? ? ? 接著再通過007中標識的rowid去對應的磁盤上讀取塊中的行數據(第4次I/O) ? ? ? ? ? ? ? ?② 索引組織表 ? ? ? ? ?? ? ? ? ? ? 前面的步驟同上,但是找到007后,由于數據和索引在一起,因此不必再找什么rowid,直接返回結果了