ⅰ、堆表
資料存放在資料裡面,索引存放在索引裡
堆就是無序資料的集合,索引就是將資料變得有序,在索引中鍵值有序,資料還是無序的
堆表中,主鍵索引和普通索引一樣的,葉子節點存放的是指向堆表中資料的指標(可以是乙個頁編號加偏移量),指向實體地址,沒有回表的說法
堆表中,主鍵和普通索引基本上沒區別,和非空的唯一索引沒區別
myisam就是用的這個堆表的儲存方式,oracle支援堆表,pg只支援堆表
ⅱ、索引組織表
我們現在都玩innodb,所以堆表一帶而過,重點關注索引組織表
對於主鍵的索引,頁子節點存放了一整行所有資料,其他索引稱為輔助索引(二級索引),它的頁子節點只是存放了鍵值和主鍵值
主鍵包含了一張表的所有資料,因為主鍵索引的頁子節點中儲存了每一行的完整記錄,包括所有列。如果沒有主鍵,mysql會自動幫你加乙個主鍵,但是對使用者不可見
innodb中資料存放在聚集索引中,換言之,按照主鍵的方式來組織資料的
其他索引(唯一索引,普通索引)的頁子節點存放該索引列的鍵值和主鍵值
不管是什麼索引非頁子節點存放的存放的就是鍵值和指標,不存資料,這個指標在innodb中是6個bit,鍵值就看資料大小了
ⅲ、兩個重點問題
3.1、乙個表a,主鍵值8個位元組,每條記錄300個位元組,每個page16k,求這張表b+ tree高度為1 能存放多少記錄,2呢? 3?
首先,乙個頁能存放16k/300個記錄
h為1,即root page 就是 leaf節點,就是大約五十條記錄
h為2,每個頁還是不變的大約50條記錄,就看頁的上層扇出一共最多能有多少指標,非頁子節點存放的就是指標和主鍵值,所以16k/(8+6) 差不多是1000,所以是50*1000條記錄
h為3,上面有兩層非頁節點,所以50 * 1000 * 1000
也就是說5000w的記錄中找乙個主鍵,只要找三個頁,一億和五百億都是找四次,所以表變大,查詢速度不會有變化,最差的hdd盤,一秒鐘能查100次,實際生產中,b+ tree 高度4層差不多了,5層很少,高度越低效能越好
dml操作,先找到頁,把這個頁讀到記憶體中,然後再去操作,只要你記憶體夠大,頁全放記憶體中,快的很
b+ tree的好處:查某個範圍內,或者某幾條資料,或者根據主鍵來查,很快,但是要把幾千萬資料查一下還要join那肯定慢了,當然也可以做定型、做hash join
缺點:插入比較慢
3.2、為什麼主鍵查詢比二級索引查詢來的快
主鍵索引裡面包含了每一行完整的資料,只要找到那個主鍵就是找到那個記錄,二級索引,如果查詢的列不是索引列,走那個列的索引找到後還要去根據索引裡儲存的主鍵去找查詢列的內容,這裡多了一步,這種查詢叫書籤查詢或者回表,如果乙個高度為3的樹,本來查只要查三個頁,走二級索引就要查六個頁
a b c 三個列,a是主鍵,b是普通索引
select c from tb;
如果走b列的普通索引,會先找到對應的a,再通過a找到對應的c
①select c where b=?
②select c where a = ?
堆表和索引組織表區別
堆表 heap table 資料插入時時儲存位置是隨機的,主要是資料庫內部塊的空閒情況決定,獲取資料是按照命中率計算,全表掃表時不見得先插入的資料先查到。索引表 iot 資料儲存是把表按照索引的方式儲存的,資料是有序的,資料的位置是預先定好的,與插入的順序沒有關係。索引表的查詢效率逼堆表高 相當於查...
堆表和索引組織表區別
堆表 heap table 資料插入時時儲存位置是隨機的,主要是資料庫內部塊的空閒情況決定,獲取資料是按照命中率計算,全表掃表時不見得先插入的資料先查到。索引表 iot 資料儲存是把表按照索引的方式儲存的,資料是有序的,資料的位置是預先定好的,與插入的順序沒有關係。索引表的查詢效率逼堆表高 相當於查...
堆表和索引組織表區別
堆表 heap table 資料插入時時儲存位置是隨機的,主要是資料庫內部塊的空閒情況決定,獲取資料是按照命中率計算,全表掃表時不見得先插入的資料先查到。索引表 iot 資料儲存是把表按照索引的方式儲存的,資料是有序的,資料的位置是預先定好的,與插入的順序沒有關係。索引表的查詢效率比堆表高 相當於查...