談談MySQL的索引

2022-05-06 07:36:10 字數 4315 閱讀 3473

目錄有什麼用

怎麼用總所周知,資料庫查詢是資料庫的最主要功能之一。我們都希望查詢資料的速度能盡可能的快。而支撐這一快速的背後就是索引;mysql索引問題也是大家經常遇到的面試題模組,想想自己也沒有去系統地總結過索引,所以記錄這篇文章來講下索引。下面還是按照是什麼->有什麼用->怎麼用->來寫

往往大家第一時間提到索引,可能就會說到它是一種資料結構,來提高查詢效率的資料結構,用在常用來查詢的字段上。但是原理是什麼呢?為什麼它就可以加快查詢?

首先,現如今,資料庫系統大多的索引底層結構是b樹或者b+樹,在資料結構的學習中,大家可能都有了解過,我們先簡單介紹下這兩種結構。

特點:每個結點都有資料,同時還有指向其下子樹的指標域,單個結構和鍊錶的基本單元相似。

每個結點乙個資料,等於就命中,小於該資料走左邊,大於走右邊

是b樹的變形,多路搜尋樹,是一種稠密索引

特點:真實的資料儲存在葉子結點的鍊錶中,其他非葉子結點並沒有資料,而是作為葉子結點的索引;鍊錶中的關鍵字是有序的。所有葉子結點都在同一層

同:都是平衡樹,每個結點到葉子結點的高度都是相同的,也保證每個查詢都是穩定,查詢的時間複雜度是log2(n),利用平衡樹的優勢是可以很大程度加快查詢的穩定性的。

異:關鍵字數量不同,儲存的位置也不同,查詢不同;b樹在找到具體的數值以後,則結束,b+樹通過索引找到葉子結點的資料才結束,也就是b+樹一定都得找到葉子結點。

對於兩種樹結構的使用和應用總結,也就是重要作用。

b樹的樹內儲存資料,因此查詢單條資料的時候,b樹的查詢效率不固定,最好的情況是o(1)。我們可以認為在做單一資料查詢的時候,使用b樹平均效能更好。但是,由於b樹中各節點之間沒有指標相鄰,因此b樹不適合做一些資料遍歷操作。

b+樹的資料只出現在葉子節點上,因此在查詢單條資料的時候,查詢速度非常穩定。因此,在做單一資料的查詢上,其平均效能並不如b樹。但是,b+樹的葉子節點上有指標進行相連,因此在做資料遍歷的時候,只需要對葉子節點進行遍歷即可,這個特性使得b+樹非常適合做範圍查詢。

接下來重點講的是mysql的索引結構。

講回索引,在mysqnl中,索引屬於儲存引擎級別的概念,而我們常常提到mysql的引擎,就會提到myisam和innodb。這裡插一下,myisam是非聚集(也叫非聚簇)索引,而innodb是聚集索引(也叫聚簇)。其實更簡單通俗得講,正文內容按照乙個特定維度排序儲存,這個特定的維度就是聚集索引;

myisam引擎使用b+tree作為索引結構,葉節點的data域存放的是資料記錄的位址,想要獲得資料,還得通過位址去獲得;同時非聚集索引索引項順序儲存,但索引項對應的內容卻是隨機儲存的;

innodb表資料檔案本身就是乙個索引結構,樹的葉節點data域儲存了完整的資料記錄,這種索引叫做聚集索引。這種索引特點是葉子結點完全包含了資料,同時innodb要求按主鍵聚集,所以也要求表要有主鍵,沒有的話系統會自動選擇乙個唯一標識資料記錄的列作為主鍵。因此,innodb的表也叫做索引表;

最後借用乙個解釋來幫助大家理解聚集索引和非聚集索引。同時這裡有個很好的例子

漢語字典提供了兩類檢索漢字的方式,第一類是拼音檢索(前提是知道該漢字讀音),比如拼音為cheng的漢字排在拼音chang的漢字後面,根據拼音找到對應漢字的頁碼(因為按拼音排序,二分查詢很快就能定位),這就是我們通常所說的字典序;第二類是部首筆畫檢索,根據筆畫找到對應漢字,查到漢字對應的頁碼。拼音檢索就是聚集索引,因為儲存的記錄(資料庫中是行資料、字典中是漢字的詳情記錄)是按照該索引排序的;筆畫索引,雖然筆畫相同的字在筆畫索引中相鄰,但是實際儲存頁碼卻不相鄰。
首先講下sql語句。

# 主要記住加索引和刪索引操作

# 可以在一開始建表時候加,也可以後面加

# alter table用來建立普通索引、unique索引或primary key索引。

alter table table_name add index index_name (column_list);

# create index可對表增加普通索引或unique索引。

create index index_name on table_name (column_list)

# 刪除

drop index index_name on talbe_name

alter table table_name drop index index_name

# 這個只在刪除主鍵的時候使用 常常一張表只有乙個主鍵

alter table table_name drop primary key

下面的是簡單使用情況以及結果分析(有索引和沒索引的分析),先看一開始表結構的索引情況

執行以下語句,建立乙個first_name_last_name索引。

use myemployees;

show tables;

desc employees;

# 建立了二級索引,是乙個聯合索引

alter table employees add index first_name_last_name

(first_name, last_name);

# 為了明確看到查詢效能,我們啟用profiling並關閉query cache:

set profiling = 1;

set query_cache_type = 0;

set global query_cache_size = 0;

# 用explain來檢視sql語句執行的情況

explain select * from employees where first_name='alyssa' and last_name like '%on';

desc employees;

# 刪除索引

drop index first_name_last_name on employees;

# 檢視無索引狀態下的執行效率

select * from employees where first_name='alyssa' and last_name like '%on';

檢視此時的索引結構,以及有了索引

執行查詢sql,看看有無索引的情況下的explain語句情況

首先是無索引下的結果

再來是有索引的

這裡解釋下我標註出來的這三個引數,其實這裡的資料量不是很大,看查詢時間差距不大,所以檢視rows的引數便可以參考下兩個查詢的區別,乙個只需一行,另乙個走了107行資料。所以說索引加快查詢效率。之所以會有快速的效果,就是由於上面的b+樹的資料結構在起作用。

就像十億個資料,如果按照常規邏輯,可能最差的情況下,需要匹配十億次才可以找到,加上這十億個資料給記憶體帶來了多少的負荷可想而知,所以要是轉化為平衡樹,可能只需要十層或者十幾層之類的樹結構,也就資料只需要花費很少的io開銷就可以找到了。這兩個的差別就是天壤之別了。

type:表示mysql在表中找到所需行的方式​ all:full table scan, mysql將遍歷全表以找到匹配的行

​ ref:表示上述表的連線匹配條件,即哪些列或常量被用於查詢索引列上的值

rows: 表示mysql根據表統計資訊及索引選用情況,估算的找到所需的記錄所需要讀取的行數

extra:該列包含mysql解決查詢的詳細資訊

最後

借鑑1借鑑2

mysql負向查詢索引 談談MySQL 索引

1 索引是什麼 索引 index 是幫助mysql高效獲取資料的資料結構。我們可以簡單理解為 索引的目的在於提高查詢效率。2 原理 索引的資料結構是b 樹,原理圖如下 精簡描述 b 樹是為了磁碟或其他直接儲存輔助裝置設計的一種平衡查詢樹。在b 樹中,所有記錄節點都是按鍵值的大小順序存放在葉子節點上,...

談談索引檔案

本來是去查b tree的,翻到了索引檔案,看了兩眼,備忘一下吧。什麼是索引檔案?除了檔案本身 即資料區 之外,另建立一張表只是邏輯記錄和物理記錄之間的意義對應關係的表 索引表,這類包括檔案資料區和索引錶兩大部分的檔案叫做索引檔案。索引表示由系統自動生成的,在記錄輸入建立資料區的同時建立乙個索引表,按...

談談資料庫索引

索引是乙個單獨的 儲存在磁碟上的資料庫結構,他們包含對資料庫裡所有記錄的引用指標。或者索引是對資料庫表中一列或多列的值進行排序的一種結構。索引的作用 提高資料庫查詢的效率。索引支援hash和b tree結構 hash 可以快速的精確查詢,但是不支援範圍查詢。所以hash索引適用於等值查詢的場景,也就...