mysql索引介紹

2022-09-06 23:36:29 字數 4613 閱讀 6625

索引是一種特殊的檔案(innodb資料表上的索引是表空間的乙個組成部分),它們包含著對資料表裡所有記錄的引用指標。好比是一本書前面的目錄,能加快資料庫的查詢速度。

無論是myisam和innodb引擎,如果在建表的時候沒有顯示的定義一行主鍵列的話,他內部都會自動建立乙個隱藏的主鍵索引;

a.大大減少伺服器需要掃瞄的資料量

b.幫助伺服器避免排序和臨時表

c.將隨機io變為順序io

索引將相關的記錄放在一起,獲得一星

索引中的資料順序和查詢中的排列順序一直,再獲得一星

索引中的列涵蓋了查詢中需要的全部列,再獲得一星

3.按照實現方式來劃分的索引型別

雜湊索引:基於雜湊表實現,只有精確匹配索引所有列的查詢才有效,只有memory引擎實現

空間資料索引(r-tree ),只有myisam引擎實現

btree索引:b-tree索引的限制:如果不是按照索引的出現順序查詢,則無法使用索引;不能跳過索引中的列,否則後面的索引無效;如果查詢中有某個列的範圍查詢,則其右邊所有列都無法使用索引優化查詢;

b+tree索引:適用於全鍵匹配、第一列匹配(組合索引)、列字首匹配,範圍值匹配、精確匹配第一列並範圍匹配第二列、只訪問索引(也稱索引覆蓋)匹配;

myisam和innodb上都是採用b+tree索引,但是實現方式完全不同。具體可參考

innodb採用聚簇索引:主鍵索引的葉子節點下面直接存放資料,其他次索引的葉子節點指向主鍵id;聚簇索引能提高多行檢索的速度。

myisam採用非聚簇索引 :主鍵索引的葉子節點只存放資料在物理磁碟上的指標,其他次索引也是一樣的;非聚簇索引對於單行的檢索很快

a.普通索引index:這是最基本的索引,它沒有任何限制。

b.唯一索引unique:與普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一

c.主鍵索引primary key:它 是一種特殊的唯一索引,不允許有空值。 

d.全文索引fulltext:僅可用於 myisam 表,針對較大的資料,生成全文索引很耗時耗空間。

e. 單列索引、多列索引:多個單列索引與單個多列索引的查詢效果不同,因為執行查詢時,mysql只能使用乙個索引,會從多個索引中選擇乙個限制最為嚴格的索引。

f.組合索引:為了榨取mysql的效率,就要考慮建立組合索引。例如表中針對title和time建立乙個組合索引:alter table article add index index_titme_time (title(50),time(10))。建立這樣的組合索引,其實是相當於分別建立了下面兩組組合索引,為什麼沒有time這樣的組合索引呢?這是因為mysql組合索引「最左字首」的結果。簡單的理解就是只從最左面的開始組合。並不是只要包含這兩列的查詢都會用到該組合索引

–title,time

–title

如果要查詢的資料恰好是索引列,那麼就不用在去物理磁碟上去找資料了,就是不用回行,稱為索引覆蓋;

雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進行insert、update和delete。因為更新表時,mysql不僅要儲存資料,還要儲存一下索引檔案。建立索引會占用磁碟空間的索引檔案。一般情況這個問題不太嚴重,但如果你在乙個大表上建立了多種組合索引,索引檔案的會膨脹很快。索引只是提高效率的乙個因素,如果你的mysql有大資料量的表,就需要花時間研究建立最優秀的索引,或優化查詢語句。

a. 何時使用聚集索引或非聚集索引?

動作描述

使用聚集索引

使用非聚集索引

列經常被分組排序

使用使用

返回某範圍內的資料

使用不使用

乙個或極少不同值

不使用不使用

小數目的不同值

使用不使用

大數目的不同值

不使用使用

頻繁更新的列

不使用使用

外來鍵列使用

使用主鍵列

使用使用

頻繁修改索引列

不使用使用

事實上,我們可以通過前面聚集索引和非聚集索引的定義的例子來理解上表。如:返回某範圍內的資料一項。比如您的某個表有乙個時間列,恰好您把聚合索引建立在了該列,這時您查詢2023年1月1日至2023年10月1日之間的全部資料時,這個速度就將是很快的,因為您的這本字典正文是按日期進行排序的,聚類索引只需要找到要檢索的所有資料中的開頭和結尾資料即可;而不像非聚集索引,必須先查到目錄中查到每一項資料對應的頁碼,然後再根據頁碼查到具體內容。

b. 索引不會包含有null值的列

只要列中包含有null值都將不會被包含在索引中,復合索引中只要有一列含有null值,那麼這一列對於此復合索引就是無效的。所以我們在資料庫設計時不要讓字段的預設值為null。

c. 使用短索引

對字串列進行索引,如果可能應該指定乙個字首長度。例如,如果有乙個char(255)的列,如果在前10個或20個字元內,多數值是惟一的,那麼就不要對整個列進行索引。短索引不僅可以提高查詢速度而且可以節省磁碟空間和i/o操作。mysql不允許索引這些列(blob、text、很長的varchar)的完整長度

d. 索引列排序

mysql查詢只使用乙個索引,因此如果where子句中已經使用了索引的話,那麼order by中的列是不會使用索引的。因此資料庫預設排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個列的排序,如果需要最好給這些列建立復合索引。

只有當索引的列順序和order by子句的順序完全一致,並且所有列的排序方向一致時,mysql才能用索引來對結果做排序

e. like語句操作:一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是乙個問題。like 「%aaa%」 不會使用索引。而like 「aaa%」可以使用索引。

f. 不要在列上進行運算:

例如:select * from users where year(adddate)<2007,將在每個行上進行運算,這將導致索引失效而進行全表掃瞄,因此我們可以改成:select * from users where adddate

g.多列索引:

如果對多個單獨索引做and條件查詢時,應該將多個單獨索引合併為乙個多列索引。

如果對多個單獨索引做or條件查詢,會消耗大量cpu、內存在演算法的快取、排序和合併上。應該將多個單獨索引合併為乙個多列索引。

使用explain檢查sql 語句,如果發現了索引合併問題,應該修改sql語句

選擇合適的索引列順序,選擇性高的列往前放

h.覆蓋索引:如果乙個索引包含所有要查詢的字段值(三星系統中第三星),較少了磁碟io操作,提高查詢效能

i.索引不能太多:索引越多會導致更新表的速度減慢,因為除了更新資料外,還要更新索引

j:mysql只對以下操作符才使用索引 ,>=,between,in,以及某些時候的like(不以萬用字元%或_開頭的情形)。而理論上每張表裡面最多可建立16個索引,不過除非是資料量真的很多,否則過多的使用索引也不是那麼好玩的

聚簇索引:資料的物理存放順序與索引順序是一致的,即:只要索引是相鄰的,那麼對應的資料一定也是相鄰地存放在磁碟上的。聚簇索引要比非聚簇索引查詢效率高很多。

聚集索引這種主+輔索引的好處是,當發生資料行移動或者頁**時,輔助索引樹不需要更新,因為輔助索引樹儲存的是主索引的主鍵關鍵字,而不是資料具體的實體地址。

innodb是聚簇索引,將主鍵組織到一棵b+樹中((所以聚簇索引的key,不能過長)),而行資料就儲存在葉子節點上,若使用"where id = 14"這樣的條件查詢主鍵,則按照b+樹的檢索演算法即可查詢到對應的葉節點,之後獲得行資料。若對name列進行條件搜尋,則需要兩個步驟:第一步在輔助索引b+樹中檢索name,到達其葉子節點獲取對應的主鍵。第二步使用主鍵在主索引b+樹種再執行一次b+樹檢索操作,最終到達葉子節點即可獲取整行資料。

每個表只能有乙個聚簇索引,因為乙個表中的記錄只能以一種物理順序存放。

非聚集索引:乙個表可以有不止乙個非聚簇索引。

myisam是非聚簇索引,b+tree的葉子節點上的data,並不是資料本身,而是資料存放的實體地址。主索引和輔助索引沒啥區別,只是主索引中的key一定得是唯一的。這裡的索引都是非聚簇索引。非聚簇索引的兩棵b+樹看上去沒什麼不同,節點的結構完全一致只是儲存的內容不同而已,主鍵索引b+樹的節點儲存了主鍵,輔助鍵索引b+樹儲存了輔助鍵。表資料儲存在獨立的地方,

這兩顆b+樹的葉子節點都使用乙個位址指向真正的表資料,對於表資料來說,這兩個鍵沒有任何差別。由於索引樹是獨立的,通過輔助鍵檢索無需訪問主鍵的索引樹。 

索引往往以索引檔案的形式儲存在磁碟上,索引的結構組織要儘量減少查詢過程中磁碟i/o的訪問次數。為了達到這個目的,磁碟按需讀取,要求每次都會預讀的長度一般為頁的整數倍。而且資料庫系統將乙個節點的大小設為等於乙個頁,這樣每個節點只需要一次i/o就可以完全載入。每次新建節點時,直接申請乙個頁的空間,這樣就保證乙個節點物理上也儲存在乙個頁裡,加之計算機儲存分配都是按頁對齊的,就實現了乙個node只需一次i/o。把b-tree中的m值設的非常大,就會讓樹的高度降低,有利於一次完全載入。 記憶體管理內容可參考作業系統記憶體管理

MySQL索引介紹

索引由資料庫表中一列或者多列組合而成,其作用是提高對錶中資料的查詢速度。建立索引是指在某個表的一列或者多列上建立乙個索引,用來提高對錶的訪問速度,建立索引由三種方法 在建立表的時候建立,在已存在的表上建立和用alter table語句建立。建立索引的基本語法格式 asc引數表示公升序排列,desc引...

MySQL索引介紹

簡單理解為 排好序的快速查詢資料結構 一般來說索引本身也很大,不可能全部儲存在記憶體中,因此索引往往以索引檔案的形式儲存在磁碟上。我們平常所說的索引,如果沒有特別指明,一般都是指b樹結構組織的索引 b 樹索引 b 樹索引檢索原理 1 類似圖書館書目索引,提高資料檢索的效率,降低資料庫的io成本。2 ...

Mysql索引介紹

索引是在建立表的時候會自動生成乙個主鍵 以主鍵生成的 索引,所以我們可以直接搜尋索引 我們也可以建立 普通索引 create index t job index on e user t job 建立索引名 被建立的表 建立的列名 格式 所以索引可以多個.刪除普通索引 drop index t job...