什麼是索引?
MySQL官方對索引的定義爲:索引(Index)是幫助MySQL高效獲取數據的數據結構。提取句子主幹,就可以得到索引的本質:索引是數據結構。
可以通俗的反過來理解索引:
你要看某一本書裏的某一章節裏的內容,如果沒有目錄的話,你是不是要從頭開始看着找呢,如果恰巧你想要看的章節內容又是在最後的那幾頁,你是不是要把書看着翻到最後呢,這效率甭想也知道很低,如果有了目錄那就好辦多了,你要看書裏的某一內容,不用從頭翻一遍,你按着目錄裏的章節去找對應內容就好了。
技術光談理論不實踐都是耍流氓,那麼我們來看看具體有哪些索引和對索引的操作
- 單值索引—— 即一個索引只包含單個列,一個表可以有uoge單列索引。
- 唯一索引—— 索引列的值必須唯一,但允許有空值。
- 複合索引—— 一個索引包含多個列。
- 全文索引—— 只有在MyISAM引擎上才能使用,只能在CHAR,VARCHAR,TEXT類型字段上使用全文索引
在做索引之前我們先創建足夠多數據,這樣才能更好的看到索引效果,那麼可以用上我們的存儲過程創建300萬條數據來玩(記住是300百萬條不是3000萬條,注意不要多個0,不然真的有得等,上一篇文章翻過車,說多都是淚,我放下面了,這裏就不贅述)
你看創建300百萬條數據也要9分鐘多,何況3000萬條…
沒有建立索引之前,我們根據username查詢一下(這裏的表結構和數據都可以去看上面鏈接裏的文章,避免有小夥伴想跟着做的無從下手)
SELECT * FROM user WHERE username = '用戶_2000000';
運行結果(查一條數據就要差不多3秒,如果用戶多了那是不行的)
那麼我們還可以用EXPLAIN關鍵字分析一下,EXPLAIN是幹嘛的呢,它可以用於分析查詢語句以及表結構的性能,也可以看是否使用了索引,以及索引的信息。
EXPLAIN SELECT * FROM user WHERE username = '用戶_2000000';
運行結果(可以看到在差不多在3000000列…)
那麼來創建一個普通索引
CREATE INDEX idx_user_username ON user(username);
查看索引
show index from user;
運行結果(可以看到除了我們手動建的索引,在表上定義主鍵後會自動創建對應的唯一索引)
創建索引後再次查詢
SELECT * FROM user WHERE username = '用戶_2000000'; -- 再次根據用戶查詢
EXPLAIN SELECT * FROM user WHERE username = '用戶_2000000'; -- 再次查詢行
運行結果(加入索引後查詢是飛速的)
看它的排是1
爲什麼建立索引會變快呢,這又回到開頭說了索引的本質是數據結構,創建索引會讓數據從一張表變成一顆B+樹,這顆樹有個特點,取中間一個數作爲根,然後小於它的往左邊,大於它的往右邊放,以此類推。(當然btree索引的數據結構深入又得是需要一篇文章來談,如果有機會咱就再寫一篇來深入看看B+樹的數據結構,這裏就不深究,下圖是一個簡單的展示,方便理解)
擴展點:
索引的優勢與劣勢
優勢:
- 上面所說書有了目錄,你找對應的內容就快多了,索引也是如此,提高了數據檢索效率,降低了IO的成本。
- 索引對數據進行了排序,降低了數據排序成本,降低了CPU的消耗。
劣勢:
- 實際索引也是一張表,該表保存了主鍵和索引字段,執行實體表的記錄,所以是要佔空間的(索引可以說是用空間換取了速度)
- 索引提高了查詢速度,但會降低更新表的速度,例如對錶進行INSERT插入、UPDATE修改、DELETE刪除。
關於優勢和劣勢還是那句話,技術是把雙刃劍,有好的一面,也會有壞的一面,沒有最好的,只有最適合的,關鍵看你在實踐中針對具體業務去運用。
索引結構:
需要注意的是我們索引數據結構還有一個hash的索引,但是我們的數據庫因爲是InnoDB的所以只支持btree(B樹)索引,而hash(哈希索引)只有MyISAM引擎支持。
有哪些情況下需要創建索引?
- 主鍵主動建立唯一索引(創建表結構的時候就需要主鍵)
- 頻繁作爲查詢條件的字段應該創建索引
- 查詢中與其他表關聯的字段,外鍵關係建立索引
- 查詢排序的的字段,排序字段通過索引再去訪問會提高排序速度
- 查詢統計或分組字段
有哪些情況下不需要創建索引?
- 表數據太少(這麼少你也建索引,這不是瞧不起我MySQL嗎 ? ? ?)
- 經常增刪改的表
- 如果某數據列有過多的重複內容,建立所以沒有太大實踐效果(還是要回到實際需求去創建對應的創建索引)
- 頻繁更新的字段不適合建立索引,因爲每次更新不單單是更新了數據,而且還會更新索引(就像書裏的目錄,你開頭都把目錄結構建好了,但你內容還老移來移去,你說目錄會不會亂)
- WHERE條件沒有用到的字段不用創建索引
最後:
看了理論和實踐,在問一句什麼是索引,你是不是又會有不同的理解了呢
對索引的的理解
- 索引用於快速找出某個列中有一特定值的行(在使用中可以看到用WHERE根據特定的值找出對應內容)。
- 不使用索引那麼它必須從第一條數據開始讀完整個表,直到找出對應的行。
- 表越大,查詢數據花費的時間就越多。
- 如果表中查詢的列有創建索引,就可以快速到達一個位置去搜索數據,而不必查看所有數據,檢索效率自然會提高。
所以技術,不僅是要能運用也要懂理論,更要清楚底層是如何實現的,要知其然也知其所以然,在深刻理解之上去創造,才能走得更遠。
我是一顆剽悍的種子,一顆偏愛前端的後端新司機。 把我會的認真的分享——一直是我寫博客的信條,把文章的知識通通帶走,把你的四連留下,點贊、評論、留言、關注是我寫博客的最大動力,哈哈