**自:
感謝大佬分享。
小夥伴們在面試的時候,有乙個特別常見的問題,那就是資料庫的回表。什麼是回表?為什麼需要回表?
對於第一點,乙個 b+tree 可以存多少條資料呢?以主鍵索引的 b+tree 為例(二級索引儲存資料量的計算原理類似,但是葉子節點和非葉子節點上儲存的資料格式略有差異),我們可以簡單算一下。
計算機在儲存資料的時候,最小儲存單元是扇區,乙個扇區的大小是 512 位元組,而檔案系統(例如 xfs/ext4)最小單元是塊,乙個塊的大小是 4kb。innodb 引擎儲存資料的時候,是以頁為單位的,每個資料頁的大小預設是 16kb,即四個塊。假設資料庫中一條記錄是 1kb,那麼乙個頁就可以存 16 條資料(葉子結點);對於非葉子結點儲存的則是主鍵值+指標,在 innodb 中,乙個指標的大小是 6 個位元組,假設我們的主鍵是 bigint ,那麼主鍵佔 8 個位元組,當然還有其他一些頭資訊也會占用位元組我們這裡就不考慮了,我們大概算一下,小夥伴們心裡有數即可:
16*1024/(8+6)=1170
1170*1170*16=21902400
可以儲存 2100萬 條資料。
在 innodb 儲存引擎中,b+tree 的高度一般為 2-4 層,這就可以滿足千萬級的資料的儲存,查詢資料的時候,一次頁的查詢代表一次 io,那我們通過主鍵索引查詢的時候,其實最多隻需要 2-4 次 io 操作就可以了。
大家知道,mysql 中的索引有很多中不同的分類方式,可以按照資料結構分,可以按照邏輯角度分,也可以按照物理儲存分,其中,按照物理儲存方式,可以分為聚簇索引和非聚簇索引。
我們日常所說的主鍵索引,其實就是聚簇索引(clustered index);主鍵索引之外,其他的都稱之為非主鍵索引,非主鍵索引也被稱為二級索引(secondary index),或者叫作輔助索引。
這就是兩者最大的區別。
對於第二種查詢方式而言,一共搜尋了兩棵 b+tree,第一次搜尋 b+tree 拿到主鍵值後再去搜尋主鍵索引的 b+tree,這個過程就是所謂的回表。
從上面的分析中我們也能看出,通過非主鍵索引查詢要掃瞄兩棵 b+tree,而通過主鍵索引查詢只需要掃瞄一棵 b+tree,所以如果條件允許,還是建議在查詢中優先選擇通過主鍵索引進行搜尋。
那麼不用主鍵索引就一定需要回表嗎?
不一定!
如果查詢的列本身就存在於索引中,那麼即使使用二級索引,一樣也是不需要回表的。
uname 和 address 字段組成了乙個復合索引,那麼此時,雖然這是乙個二級索引,但是索引樹的葉子節點中除了儲存主鍵值,也儲存了 address 的值。
可以看到,此時使用到了 uname 索引,但是最後的 extra 的值為using index
,這就表示用到了索引覆蓋掃瞄(覆蓋索引),此時直接從索引中過濾不需要的記錄並返回命中的結果,這一步是在 mysql 伺服器層完成的,並且不需要回表。
基於第一、二小節的分析,我們再來捋一捋為什麼在資料庫中建議使用自增主鍵。
當然,這個是基於技術層面的討論,如果業務上無法使用自增主鍵或者有其他要求導致無法使用自增主鍵,那沒辦法,在滿足新要求的情況下重新選擇乙個最佳實踐吧。
mysql 回表 什麼是MYSQL回表查詢
select id,name where name shenjian select id,name,where name shenjian 多查詢了乙個屬性,為何檢索過程完全不同?什麼是回表查詢?什麼是索引覆蓋?如何實現索引覆蓋?哪些場景,可以利用索引覆蓋來優化sql?這些,這是今天要分享的內容。畫...
MySQL優化 如何避免回表查詢?什麼是索引覆蓋?
我們知道mysql底層使用的b 樹來儲存索引的,而且資料都存在葉子節點上。對於innodb來說,它的主鍵索引和行記錄是儲存在一起的,因此叫做聚集索引。ps myisam的行記錄是單獨儲存的,不和索引在一起,因此myisam是沒有聚集索引的。除了聚集索引,其他的索引都叫非聚集索引。普通索引,唯一索引等...
mysql 回表查詢是什麼
在說到什麼是回表查詢的時候,有兩個概念需要先解釋清楚 分別是聚集索引 聚簇索引 和非聚集索引 非聚簇索引 mysql規定,在使用innodb儲存引擎的時候,必須且僅有乙個聚集索引,非聚集索引也就是普通索引就看自己設定的有多少個了 聚集索引和非聚集索引的區別 1.聚集索引中的非葉子節點儲存的是表的主鍵...