Mysql為什麼添加索引可以提高查詢速度,看完這篇就夠了

2020-12-17 王者小哆啦

這篇文章我會分為以下部分進行講解,如果你懂了,那麼請繞行,別浪費你寶貴時間!

只有光頭才可以變強,如果你要繼續看,請保持空杯心態!

為什麼添加索引會提高查詢速度總結。索引提高了查詢速度對增刪改有影響嗎。索引常用的算法原理分析B樹和B+樹等。

為什麼添加索引會提高查詢速度

一句話回答:索引可以將無序內容轉換為有序的一個集合(相對),就如同新華字典,如果沒有目錄,那麼查詢一個漢字就需要很長時間了。

找到id=8的只需要這幾步

最後總結一點:如果沒有索引我們查詢數據是需要遍歷雙向鍊表來定位對應的page,現在通過索引創建的「目錄」就可以很快定位對應頁上了!

其實底層實現的結構就是B+樹,B+樹作為樹的一種實現能夠讓我們很快查找出對應內容。

索引可以提高查詢速度,但是會降低增刪改的速度,為什麼

任何事情都有有利有弊,在於你自己權衡利弊。

首先來說B+樹就是平衡樹的一種。

NOTE:平衡樹它就是一顆空樹或者說它左右兩個子樹的高度相差的絕對值不會超過1,並且左右兩個子樹都是一顆平衡二叉樹。

如果一棵普通B樹在極端情況下是有可能退化成鍊表的,這樣所謂的查詢提速也就不存在了

前面我們就說了B+樹本身就是平衡樹,所以它是不會退化成鍊表的,樹的高度都是比較低的(矮胖墩)【正因為這一點,我們的檢索時間複雜度為O】,在上面添加索引會提高查詢速度中我們介紹的建立索引,說白了就是建立一個B+樹。

B+樹是一顆平衡樹,如果我們對這棵樹增刪改的話,那肯定會破壞它的原有結構。要維持平衡樹,就必須做額外的工作。正因為這些額外的工作開銷,導致索引會降低增刪改的速度

索引常用的算法原理分析:B樹和B+樹等

和索引相關的算法:二分查找法、二叉查找樹、平衡二叉樹、B樹、B+樹,內容長,但很有用,如果看、耐心看,珍惜時間!

我們在這些數字中用不同算法(1、2、3、5、6、7、9)找出6。

二分查找法原理:先將記錄按順序排列,查找時先按序列的中點位置為比較對象,如果要找的元素值小於該中點元素,則將查詢範圍縮小為左半部分;如果要找的元素值大於該中點元素,則將查詢範圍縮小為右半部分。以此類推,直到查到需要的值。

比如我們要找6,用了 3 次就查找到 6 這個數字了。如果是順序查找,則需要查詢 5 次(從第一個數字 1 開始,如果發現不是 6,則繼續查找下一個,直到查詢到 6)。

我們來對比一下這個例子順序查找和二分查找法的平均查找次數:

順序查找:(1 + 2 + 3 + 4 + 5 + 6 + 7)/7 = 4 次

二分查找法:(3 + 2 + 3 + 1 + 3 + 2 + 3)/7 ≈ 2.4 次

顯然二分查找法相對順序查找平均效率更高。

二叉樹查找原理:二叉查找樹中,左子樹的鍵值總是小於根的鍵值,右子樹的鍵值總是大於根的鍵值,並且每個節點最多只有兩顆子樹。

還是找6,這組數字的平均查找次數為:(3 + 2 + 1 + 2 + 3 + 4 + 5)/7 ≈ 2.9 次

試想一下,如果 3 的右子樹後面拖更多的數字,那查詢效率得多低啊!

此時,平衡二叉樹出場了。

平衡二叉樹的定義:滿足二叉查找樹的定義,另外必須滿足任何節點的兩個子樹的高度差最大為 1。

如果要查值為 6 的記錄,先找到根(這裡是 5 ),這裡借用二分查找的思想,因為要找的值 6 大於中點元素 5,所以需要查找的是 5 的右子樹,而又因為 6 小於 7,則應該找 7 的左子樹,找到 6 這條記錄,一共查找了 3 次。如果查找記錄使用順序查找,找到 6 這個值需要查 5 次。

平衡二叉查找樹的平均查找次數:(3 * 4 + 2 * 2 + 1) /7 ≈ 2.4 次

計算方式:該平衡二叉查找樹中 4 個第三層的值需要查找 3 次,2 個第二層的值需要查找 2 次,第一層也就是根的值只需要查 1 次。

上面我們說了順序查找需要查找4次,比起來顯然平衡二叉查找樹的平均查找速度比順序查找更快。

但是平衡二叉樹有個缺點就是,每個節點最多只有兩個分支,如果數據量比較大,要經歷多層節點才能查詢在葉子節點的數據。

如果在平衡二叉樹的基礎上,每個節點可以有多個分支,那即使在葉子節點的數據,是不是查詢效率也比較高呢?這就引出了 B 樹結構。

B 樹可以理解為一個節點可以擁有多於 2 個子節點的多叉查找樹。B 樹中同一鍵值不會出現多次,要麼在葉節點,要麼在葉的子節點上。

比如用 1、2、3、5、6、7、9 這些數字構建一個 B 樹結構,其圖形如下:

與平衡二叉樹相比,B 樹利用多個分支(平衡二叉樹只有兩個分支)節點,減少獲取記錄時所經歷的節點數。

B 樹也是有缺點,因為每個節點都包含 key 值和 data 值,因此如果 data 比較大時,每一頁存儲的 key 會比較少;當數據比較多時,同樣會有:「要經歷多層節點才能查詢在葉子節點的數據」的問題。這時,B+ 樹站了出來。

B+ 樹是 B 樹的變體,定義基本與 B 樹一致

B樹和B+樹不同點:

所有葉子節點中包含了全部關鍵字的信息各葉子節點用指針進行連接非葉子節點上只存儲 key 的信息,這樣相對 B 樹,可以增加每一頁中存儲 key 的數量。B 樹是縱向擴展,最終變成一個「瘦高個」,而 B+ 樹是橫向擴展的,最終會變成一個「矮胖子」。在 B+ 樹中,所有記錄節點都是按鍵值的大小順序存放在同一層的葉子節點上。B+ 樹中的 B 不是代表二叉(binary) 而是代表(balance),B+ 樹並不是一個二叉樹。

B+與B樹最大的區別就是:B+樹它的鍵一定會出現在葉子節點上,同時也有可能在非葉子節點中重複出現。而 B 樹中同一鍵值不會出現多次。

總結

到此為止基本mysql查找算法就全部講完了,下一篇我們主要來看mysql的聚簇索引和非聚簇索引。

這篇文章重點知識:為什麼索引可以加速查詢,加速查詢算法的實現原理。

相關焦點

  • Mysql索引:表在哪些情況下需要加索引,應該加哪種索引,你懂嗎
    Mysql為什麼添加索引可以提高查詢速度,看完這篇就夠了本章適合學習完成上一章內容的同學學習在前面兩篇文章中我們了解到了mysql索引的重要性,那麼我們的數據表到底在哪種情況下才適合添加索引呢?索引有好多種我們應該添加哪種呢?今天我們就來一起聊聊這個問題。
  • Mysql索引:深入理解InnoDb聚集索引與MyisAm非聚集索引值得一看
    Mysql為什麼添加索引可以提高查詢速度,看完這篇就夠了導讀:本篇理論知識比較多問題:關於索引搜索問題,聚集索引可以直接找到數據,對於非聚集索引需要回表查詢,那麼select count(*) from table 是否需要回表查詢呢?why?
  • 面對MySQL 查詢索引失效,程式設計師的六大優化技巧!
    不知道你有沒有碰到過這種情況,一條創建了索引的SQL語句在查詢過程中卻沒有使用索引,或是一條本來可以執行的很快的語句,卻由於MySQL選錯了索引,而導致查詢速度變得很慢?充分優化和利用索引能夠大大提高數據的查詢效率,但是在實際的應用中MySQL可能並不總會選擇合適且效率高的索引。
  • 「看這篇就夠了」Mysql join條件是要寫在on裡還是在where裡?
    我們先建兩個表和添加一批數據,注意只有a表的f1有索引,a表和B表的數據不完全一致:結果集區別上圖可以看出,結果集是不一樣的,條件寫在ON裡,數據有6條,比條件放在where裡面多出2條。「看這篇就夠了」Mysql大表中查詢全表掃描是否會佔用完內存?
  • 什麼是 MySQL 索引?
    這就像用人眼從頭到尾瀏覽整張表,很慢也不優雅,「索引」派上用場的時候到了,使用索引的全部意義就是:通過縮小一張表中需要查詢的記錄/行的數目來加快搜索的速度。 在關係型資料庫中,索引是一種單獨的、物理的對資料庫表中一列或多列的值進行排序的一種存儲結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些值的數據頁的邏輯指針清單(定義真特麼拗口)。
  • 面試官:Mysql索引原理是什麼?看這篇就夠了!
    提取關鍵字:索引是一種數據結構,可以快速訪問資料庫表提取信息。先來思考一下:為什麼要創建索引?定義說了,可以快速提取信息,也就是一個快速查找的過程;資料庫存在的意義之一就是是解決數據存儲和快速查找的。那麼資料庫的數據存在哪?沒錯,是磁碟,磁碟的優點是啥?便宜!缺點是啥?訪問速度慢,當然這是對比內存來說的。
  • MySQL 的索引是什麼?怎麼優化?
    索引類似大學圖書館建書目索引,可以提高數據檢索的效率,降低資料庫的IO成本。MySQL在300萬條記錄左右性能開始逐漸下降,雖然官方文檔說500~800w記錄,所以大數據量建立索引是非常有必要的。MySQL提供了Explain,用於顯示SQL執行的詳細信息,可以進行索引的優化。1.硬體問題。如網絡速度慢,內存不足,I/O吞吐量小,磁碟空間滿了等。
  • MySQL 這該死的 「IN (子查詢)」
    *,(SELECT MAX(id) FROM t2 WHERE t1.id = t2.id) FROM t1 WHERE t1.id%2 = 0;從上我們不難發現:對於「非關聯子查詢」,子查詢只用執行一次,執行完後結果會被存入到臨時表,不管這一次是走上索引了,還是全表掃描,最大成本是一次全表掃描。
  • MySQL 面試索引全篇,索引面試掌握這些就夠了
    非聚集索引在建立的時候也未必是單列的,可以多個列來創建索引,本質區別是表記錄的排列順序和索引的排列順序是否一致。聚集索引的葉節點就是數據節點,而非聚簇索引的葉節點仍然是索引節點,並保留一個連結指向對應數據塊。聚簇索引主鍵的插入速度要比非聚簇索引主鍵的插入速度慢很多。
  • 千萬級MySQL資料庫這樣建索引可以讓你的資料庫飛起來
    MySql在索引優化時需要注意的問題設計好MySql的索引可以讓你的資料庫飛起來,大大的提高資料庫效率。創建索引:對於查詢佔主要的應用來說,索引顯得尤為重要。很多時候性能問題很簡單的就是因為我們忘了添加索引而造成的,或者說沒有添加更為有效的索引導致。如果不加索引的話,那麼查找任何哪怕只是一條特定的數據都會進行一次全表掃描,如果一張表的數據量很大而符合條件的結果又很少,那麼不加索引會引起致命的性能下降。但是也不是什麼情況都非得建索引不可,比如性別可能就只有兩個值,建索引不僅沒什麼優勢,還會影響到更新速度,這被稱為過度索引。
  • MySQL 工作、底層原理,看這一篇就夠了!
    將這兩個查詢條件聯接起來生成最終查詢結果.注意點(1)如何緩存查詢數據存儲引擎處理完數據,並將其返回給程序的同時,它還會將一份數據保留在緩存中,以便更快速的處理下一次相同的請求。具體情況是,mysql會將查詢的語句、執行結果等進行hash,並保留在cache中,等待下次查詢。
  • MySQL索引與索引優化
    首先明白為什麼索引會增加速度?DB在執行一條Sql語句的時候,默認的方式是根據搜索條件進行全表掃描,遇到匹配條件的就加入搜索結果集合。如果我們對某一欄位增加索引,查詢時就會先去索引列表中一次定位到特定值的行數,大大減少遍歷匹配的行數,所以能明顯增加查詢的速度。
  • 索引為什麼能提高查詢性能
    她又不緊不慢的問,索引為什麼就能提高查詢性能。這還用問,索引就像一本書的目錄,用目錄查當然很快。她失望地搖了搖頭,你說的只是一個類比,可為什麼通過目錄就能提高查詢速度呢。唉,對啊,通過書目可以快速查詢,這只是一個現象,真正原因到底是什麼呢。
  • 為什麼Mongodb索引用B樹,而MySQL用B+樹?
    因此,就有了這篇文章的誕生~文末附面試指南!正文這裡的Mysql指的是Innodb的存儲引擎下的索引結構,其他存儲引擎我們暫時不討論。但是,B+樹的葉子節點上有指針進行相連,因此在做數據遍歷的時候,只需要對葉子節點進行遍歷即可,這個特性使得B+樹非常適合做範圍查詢。因此,我們可以做一個推論:沒準是Mysql中數據遍歷操作比較多,所以用B+樹作為索引結構。而Mongodb是做單一查詢比較多,數據遍歷操作比較少,所以用B樹作為索引結構。那麼為什麼Mysql做數據遍歷操作多?
  • 如何查看 sql 查詢是否用到索引 ( mysql )
    用於區別普通查詢、聯合查詢、子查詢等的複雜查詢。table: 輸出結果集的表 顯示這一步所訪問資料庫中表名稱(顯示這一行的數據是關於哪張表的),有時不是真實的表名字,可能是簡稱,例如上面的e,d,也可能是第幾步執行的結果的簡稱type:對表訪問方式,表示MySQL在表中找到所需行的方式,又稱「訪問類型」。
  • mysql索引分類及原理
    ,而不能使用LIKE %查詢字符串%的模糊查詢語法SELECT * FROM table_name MATCH(ft_index) AGAINST('查詢字符串');注意:對於較大的數據集,把數據添加到一個沒有FULLTEXT索引的表,然後添加FULLTEXT索引的速度比把數據添加到一個已經有FULLTEXT索引的表快。
  • 月薪3W,面試官問:詳細聊聊MySQL中 聚簇、非聚簇索引和覆蓋索引
    因此,利用索引會使資料庫查詢有驚人的性能提升。當然任何事物都是有兩面的,索引能讓資料庫查詢數據的速度提升, 同時對表的寫入數據速度就會下降,原因很簡單的。 因為平衡樹這個結構必須一直維持在一個正確的狀態,增刪改數據都會改變平衡樹各節點中的索引數據內容,破壞樹結構。
  • MySQL優化:學會使用show profile和trace分析慢查詢
    看本篇之前建議先看上篇:1.5 關閉profilemysql> set profiling=off;trace 分析 SQL 優化器從前面學到了 explain 可以查看 SQL 執行計劃,但是無法知道它為什麼做這個決策,如果想確定多種索引方案之間是如何選擇的或者排序時選擇的是哪種排序模式
  • MySQL,多列索引
    這樣一來 最好的情況下也只能是「一星」索引,其性能比起真正最優的索引可能差幾個數量級。有時如果無法設計一個「三星」索引,那麼不如忽略掉WHERE子句,集中精力優化索引列的順序,或者創建一個全覆蓋索引。在多個列上建立獨立的單列索引大部分情況下並不能提高MySQL的查詢性能。
  • 索引為什麼能提高查詢性能....
    這簡直是一道送分題,我自豪且略帶鄙夷的說,當然是加「索引」了。她又不緊不慢的問,索引為什麼就能提高查詢性能。這還用問,索引就像一本書的目錄,用目錄查當然很快。她失望地搖了搖頭,你說的只是一個類比,可為什麼通過目錄就能提高查詢速度呢。