MySQL優(yōu)化及索引解析
索引簡單介紹
索引的本質(zhì):
- MySQL索引或者說其他關(guān)系型數(shù)據(jù)庫的索引的本質(zhì)就只有一句話,以空間換時間。
索引的作用:
- 索引關(guān)系型數(shù)據(jù)庫為了加速對表中行數(shù)據(jù)檢索的(磁盤存儲的)數(shù)據(jù)結(jié)構(gòu)
索引的分類
數(shù)據(jù)結(jié)構(gòu)上面的分類:
- HASH 索引
- 等值匹配效率高
- 不支持范圍查找
- 樹形索引
- 二叉樹,遞歸二分查找法,左小右大
- 平衡二叉樹,二叉樹到平衡二叉樹,主要原因是左旋右旋
- 缺點1,IO次數(shù)過多
- 缺點2,IO利用率不高,IO飽和度
- 多路平衡查找樹(B-Tree)
- 特點,大大的減少了樹的高度
- B+樹
- 特點,采用左閉合的比較方式
- 根節(jié)點支節(jié)點沒有數(shù)據(jù)區(qū),只有葉子結(jié)點才包含數(shù)據(jù)區(qū)(說白了就是即便在根節(jié)點和子節(jié)點已經(jīng)定位到,因為沒有數(shù)據(jù)區(qū)的原因也不會停留,會一直找到葉子結(jié)點為止。)
當我們搜索13這條數(shù)據(jù)時,在根節(jié)點和子節(jié)點 都能定位,但是一直會找到葉子結(jié)點。
二叉樹平衡二叉樹,B樹對比:
如圖顯示如果是自增主鍵情況下:
二叉樹顯然不適合做關(guān)系型數(shù)據(jù)庫索引(和全表掃描沒什么區(qū)別)。
平衡二叉樹呢,雖然解決了這種情況,但是同樣會導致這棵樹,又瘦又高,這同樣會造成上文所提到查詢IO次數(shù)過多以及IO利用率不高。
B樹呢,顯然已經(jīng)解決了這兩個問題,所以下文來解釋,為什么在這種情況下MySQL還用了B+樹,又做了那些增強。
B樹和B+樹比較:
B+樹在B樹上面的優(yōu)化:
IO效率更高(B樹每個節(jié)點都會保留數(shù)據(jù)區(qū),而B+樹則不會,假設(shè)我們查詢一條數(shù)據(jù)要遍歷三層,那么顯然B+樹查詢中IO消耗更小)
范圍查找效率更高(如圖,B+樹已經(jīng)形成了一個天然鏈表形式,只需要根據(jù)最結(jié)尾的鏈式結(jié)構(gòu)查找)
基于索引的數(shù)據(jù)掃描效率更高。
索引類型的分類
索引類型可分為兩類:
- 主鍵索引
- 輔佐索引(二級索引)
- 唯一性索引
- 復(fù)合索引
- 普通索引
- 覆蓋索引
主鍵索引相對來說性能是最好的,但是對于SQL優(yōu)化,其實大多時候我們都在輔佐索引上面做一些改進和補充。
B+樹在儲存引擎層面落地
- 我們創(chuàng)建兩個表分別為
test_innodb
(采用InnoDB作為儲存引擎)test_myisam(采用MyISAM作為儲存引擎)下圖是兩張表磁盤落地的相關(guān)文件,這兩個儲存引擎在B+樹磁盤落地式截然不同的。
B+樹在MyISAM落地:
- *.frm文件是表格骨架文件比如這個表中的id字段name字段是什么類型的存儲在這里
- *.MYD(D=data)則儲存數(shù)據(jù)
- *.MYI (I=index)則儲存索引
- 比如現(xiàn)在執(zhí)行如下sql語句 ,那么在MyISAM中他就是先在test_myisam.MYI中查找到103然后拿到0x194281這個地址然后再去test_myisam.MYD中找到這個數(shù)據(jù)返回。
SELECT id,name from test_myisam where id =103
- 如果
test_myisam
表中,id為主鍵索引,name也是一個索引,那么在test_myisam.MYI中則會有兩個平級的B+樹,這也導致MyISAM引擎中主鍵索引和二級索引是沒有主次之分的,是平級關(guān)系。因為這種機制在MyISAM引擎中,有可能使用多個索引,在InnoDB中則不會出現(xiàn)這種情況。
B+樹在InnoDB落地:
- InnoDB不像MyISAM來獨立一個MYD 文件來存儲數(shù)據(jù),它的數(shù)據(jù)直接存儲在葉子結(jié)點關(guān)鍵字對應(yīng)的數(shù)據(jù)區(qū)在這保存這一個id列所有行的詳細記錄。
- InnoDB 主鍵索引和輔助索引關(guān)系
我們現(xiàn)在執(zhí)行如下SQL語句,他會先去找輔助索引,然后找到輔助索引下101的主鍵,再去回表(二次掃描)根據(jù)主鍵索引查詢103這條數(shù)據(jù)將其返回。
SELECT id,name from test_myisam where name ='zhangsan'
這里就有一個問題了,為什么不像MyISAM在輔助索引下直接記錄磁盤地址,而是要多此一舉再去回表掃描主鍵索引,這個問題在下面相關(guān)面試題中回答,記一下這個問題是這里來的。
相關(guān)面試題
- 為什么MySQL選擇B+樹作為索引結(jié)構(gòu)
這個就不說了,上文應(yīng)該講清楚了。
- B+樹在MyISAM和InnoDB落地區(qū)別。
這個可以總結(jié)一下,MyISAM落地數(shù)據(jù)儲存會有三個類型文件 ,.frm文件是表骨架文件,.MYD(D=data)則儲存數(shù)據(jù) ,.MYI (I=index)則儲存索引,MyISAM引擎中主鍵索引和二級索引平級關(guān)系,在MyISAM引擎中,有可能使用多個索引,InnoDB則相反,主鍵索引和二級索有嚴格的主次之分在InnoDB一條語句只能用一個索引要么不用。
- 如何判斷一條sql語句是否使用了索引。
可以通過執(zhí)行計劃來判斷 可以在sql語句前explain/ desc
set global optimizer_trace='enabled=on' 打開執(zhí)行計劃開關(guān)他將會把每一條查詢sql執(zhí)行計劃記錄在information_schema 庫中OPTIMIZER_TRACE表中
- 為什么主鍵索引最好選擇自增列?
自增列,數(shù)據(jù)插入時整個索引樹是只有右邊在增加的,相對來說索引樹的變動更小。
- 為什么經(jīng)常變動的列不建議使用索引?
和上一個問題原因一樣,當一個索引經(jīng)常發(fā)生變化,那么就意味這,這個縮印樹也要經(jīng)常發(fā)生變化。4
- 為什么說重復(fù)度高的列,不建議建立索引?
這個原因是因為離散性,比如說,一張一百萬數(shù)據(jù)的表,其中一個字段代表性別,0代表男1代表女,把這字段加了索引,那么在索引樹上,將會有大量的重復(fù)數(shù)據(jù)。而我們常見的索引建立一般都是驅(qū)動型的。其目的是,盡可能的刪減數(shù)據(jù)的查詢范圍,這個顯然是不匹配的。
- 什么是聯(lián)合索引
聯(lián)合索引是一個包含了多個功效的索引,他只是一個索引而不是多個,
其次,單列索引是一種特殊的聯(lián)合索引
聯(lián)合索引的創(chuàng)立要遵循最左前置原則(最常用列>離散度>占用空間?。?/p>
- 什么是覆蓋索引
通過索引項信息可直接返回所需要查詢的索引列,該索引被稱之為覆蓋索引,說白了就是不需要做回表操作,可以從二級索引中直接取到所需數(shù)據(jù)。
- 什么是ICP機制
索引下推,簡單點來說就是,在sql執(zhí)行過程中,面對where多條件過濾時,通過一個索引,完成數(shù)據(jù)搜索和過濾條件其,特點能減少io操作。
- 在InnoDB表中不可能沒有主鍵對還是不對原因是什么?
首先這句話是對的,但是情況有三種:
- 就是在你手動顯式指定這一個字段為主鍵時候,會以這一個字段為聚集索引。
- 在沒有顯式指定主鍵時候有兩種情況:
- 他會尋找第一個UK(unique key)作為主鍵索引組織索引編排。
- 如果既沒有指定主鍵也沒有UK的情況下,此時會以rowId(在InnoDB表中每一個記錄都會有一個隱藏(6byte)的rowId)為聚集索引。
- 什么是回表操作
在InnoDB 中基于輔助索引查詢的內(nèi)容,從輔助索引中無法直接獲取,需要基于主鍵索引的二次掃描的操作叫做回表操作。
- 為什么在InnoDB 中輔助索引葉子結(jié)點數(shù)據(jù)區(qū)記錄的是主鍵索引的值而不是像MyISAM中去記錄磁盤地址。
這個原因其實很簡單,因為主鍵索引的數(shù)據(jù)結(jié)構(gòu)是會經(jīng)常發(fā)生變化的,如果在輔助索引數(shù)據(jù)區(qū)記錄磁盤地址,那么假設(shè)我們有10個輔助索引,當我們主鍵索引結(jié)構(gòu)發(fā)生變化后,還要一個個去通知輔助索引,且主鍵索引結(jié)構(gòu)是經(jīng)常發(fā)生變化的,增刪都有可能影響他的
數(shù)據(jù)結(jié)構(gòu)。
到此這篇關(guān)于MySQL優(yōu)化及索引解析的文章就介紹到這了,更多相關(guān)MySQL優(yōu)化索引內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
修改MySQL數(shù)據(jù)庫中表和表中字段的編碼方式的方法
這篇文章主要介紹了如何修改MySQL數(shù)據(jù)庫中表和表中字段的編碼方式,需要的朋友可以參考下2014-05-05深入淺析MySQL從刪庫到跑路_高級(一)——數(shù)據(jù)完整性
數(shù)據(jù)完整性是指數(shù)據(jù)的可靠性和準確性,數(shù)據(jù)完整性類型有四種,本文給大家提到,接下來通過本文給大家介紹MySQL從刪庫到跑路的內(nèi)容分析,感興趣的朋友跟隨小編一起看看吧2018-11-11MySQL遞歸查找樹形結(jié)構(gòu)(這個方法太實用了!)
對于數(shù)據(jù)庫中的樹形結(jié)構(gòu)數(shù)據(jù),如部門表,有時候,我們需要知道某部門的所有下屬部分或者某部分的所有上級部門,這時候就需要用到mysql的遞歸查詢,下面這篇文章主要給大家介紹了關(guān)于MySQL遞歸查找樹形結(jié)構(gòu)的相關(guān)資料,需要的朋友可以參考下2022-11-11Windows server 2008 r2下MySQL5.7.17 winx64安裝版配置方法圖文教程
這篇文章主要為大家詳細介紹了Windows server 2008 r2下MySQL5.7.17 winx64安裝版配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03