這小夥子把MySQL索引使用講的真明白,真好,快來戳他

點贊多大膽,就有多大產!開源促使進步,獻給每一位技術使用者和愛好者!

乾貨滿滿,擺好姿勢,點贊發車

前言

不管在學習數據庫或者在面試時都會遇到索引這個玩意兒,是我們走向光頭必不可少的一項技能!對於數據庫如何優化,都會想到加索引,我們就來說說到底什麼是索引,怎麼用,如何用好等!索引數據結構請戳《搞懂MySQL數據庫索引數據結構這一篇足夠從此不再萌萌噠》,話不多說直接開搞!

索引你做個自我介紹

各位看客老爺我是索引,我其實很簡單不像外邊的妖豔賤貨那麼複雜,官網上說人家是存儲引擎用於快速找到記錄的一種數據結構,不通的存儲引擎對索引的實現方式不同,一般存儲在磁盤中,爲了減少數據掃描的次數,將隨機I/O轉變爲順序I/O,幫助我們在分組、排序等操作時,避免使用臨時表。比如新華字典,要去找一個字可以通過翻目錄用偏旁,拼音等來找一個字,如果沒有這個目錄你就得一頁一頁去找,索引就是數據庫性能調優的基礎方式,常用於實現數據的快速檢索,接下來我要給大家好好介紹一下索引。

MySql數據訪問方式

在Mysql中通常有以下兩種方式來檢索一行數據,如以下數據表

id name age
1 石添添 18
2 石小添 19
3 石笑天 10
4 石小索 15
5 石小引 21
6 石以初 20

順序訪問

順序訪問是執行全表掃描,比如我們要檢索age爲15的用戶,從頭到尾逐行遍歷,直到在無序的行數據中找到符合條件的目標數據。這種方式實現比較簡單,但是當表中有大量數據的時候,效率非常低下。例如,在幾千萬條數據中查找少量的數據時,使用順序訪問方式將會遍歷所有的數據,花費大量的時間,顯然會影響數據庫的處理性能!

索引訪問

索引訪問是通過遍歷索引來直接訪問表中記錄行的方式。使用這種方式的前提是對錶建立一個索引,在列上創建了索引之後,查找數據時可以直接根據該列上的索引找到對應記錄行的位置,從而快捷地查找到數據。

例如:我們在age列上添加索引,數據庫系統就建立了一張索引列到實際記錄的映射表,當需要查找age爲15的數據時,會先在age索引上找到該記錄,然後通過映射表直接找到數據行,並且返回該行數據。因爲掃描索引的速度一般遠遠大於掃描實際數據行的速度,所以採用索引的方式可以大大提高數據庫的工作效率。

至此我們知道索引是一種數據結構,需要單獨存放可以增快我們的查詢效率,是數據庫優化的一種基礎而重要方案,數據庫搜索數據順序訪問索引訪問兩種方式。

索引創建

MySql提供三種創建索引的方法,注意InnoDB引擎會自動在主鍵上添加索引

使用CREATE INDEX 語句

用於在表已存在添加索引

語法

CREATE INDEX <索引名> ON <表名> (<列名> [<長度>] [ ASC | DESC])

說明

  • 索引名:指定索引名。一個表可以創建多個索引,但每個索引名在表中唯一
  • 表名:指定在哪個表中創建索引
  • 列名:指定要創建索引的列名。通常可以考慮將查詢語句中在 JOIN 子句和 WHERE 子句裏經常出現的列作爲索引列,可以是一列也可以是多列,一列的稱之爲單列索引,多列成爲組合索引
  • 長度:可選項。指定使用列前的 length 個字符來創建索引。使用列的一部分創建索引有利於減小索引文件的大小,節省索引列所佔的空間。在某些情況下,只能對列的前綴進行索引。索引列的長度有一個最大上限 255 個字節(MyISAM 和 InnoDB 表的最大上限爲 1000 個字節),如果索引列的長度超過了這個上限,就只能用列的前綴進行索引。另外,BLOB 或 TEXT 類型的列也必須使用前綴索引
  • ASC | DESC:可選項。ASC指定索引按照升序來排列,DNSC指定索引按照降序來排列,默認爲ASC

例子 

CREATE INDEX index_user_age ON tb_user(age);

使用CREATE TABLE 語句

用於在創建表(CREATE TABLE)時創建,在CREATE TABLE 語句下添加

語法

1、表示在創建新表的同時創建該表的索引

KEY | INDEX [<索引名>] [<索引類型>] (<列名>,…)

2、表示在創建新表的同時創建該表的唯一性索引

UNIQUE [ INDEX | KEY] [<索引名>] [<索引類型>] (<列名>,…)

例子

CREATE TABLE student(
id INT PRIMARY KEY,
`name` VARCHAR(10) NOT NULL,
class VARCHAR(10) NOT NULL,
INDEX(name) -- 在name列上創建索引
);

 使用 ALTER TABLE 語句

在使用 ALTER TABLE 語句修改表的同時,可以向已有的表添加索引。具體的做法是在 ALTER TABLE 語句中添加以下語法成分的某一項或幾項

語法

1、在修改表的同時爲該表添加索引

ADD INDEX [<索引名>] [<索引類型>] (<列名>,…)

2、在修改表的同時爲該表添加唯一性索引

ADD UNIQUE [ INDEX | KEY] [<索引名>] [<索引類型>] (<列名>,…)

 例子

ALTER TABLE student ADD INDEX index_class (class);

查看索引

語句

SHOW INDEX FROM <表名> [ FROM <數據庫名>]

例子

SHOW index FROM table_name;

 說明

  • 表名:查詢索引的表名
  • 數據庫名:要查詢的表在哪個數據庫,這個可以使用數據庫名.表名替代
  • Table:表名
  • No_unique:用於顯示該索引是否是唯一索引。若不是唯一索引,則該列的值顯示爲 1;若是唯一索引,則該列的值顯示爲 0
  • Key_name:索引的名稱,不指定名稱就是列名
  • Seq_in_index:索引中的列序列號,從1開始計數
  • Column_name:列名
  • Collation:顯示列以何種順序存儲在索引中。在 MySQL 中,升序顯示值“A”,若顯示爲 NULL,則表示無分類
  • Cardinality:顯示索引中唯一值數目的估計值。基數根據被存儲爲整數的統計數據計數,所以即使對於小型表,該值也沒有必要是精確的。基數越大,當進行聯合時,MySQL 使用該索引的機會就越大
  • Sub_part:若列只是被部分編入索引,則爲被編入索引的字符的數目。若整列被編入索引,則爲 NULL
  • Packed:指示關鍵字如何被壓縮。若沒有被壓縮,則爲 NULL
  • Null:用於顯示索引列中是否包含 NULL。若列含有 NULL,則顯示爲 YES
  • Index_type:顯示索引使用的類型和方法(BTREE、FULLTEXT、HASH、RTREE)
  • Comment:顯示評註
  • Index_comment:顯示評註

刪除索引

當老闆不再用我的時候,可以使用 DROP INDEX 語句或 ALTER TABLE 語句來刪除我!

刪除

語法

DROP INDEX <索引名> ON <表名>
或者再ALTER TABLE語句後邊添加
DROP INDEX index_name:表示刪除名稱爲 index_name 的索引。

注意:如果刪除的列是索引的組成部分,那麼在刪除該列時,也會將該列從索引中刪除;如果組成索引的所有列都被刪除,那麼整個索引將被刪除

例子

DROP INDEX name ON student;
或
ALTER TABLE student DROP INDEX index_class;

索引分類

根據索引的用途在邏輯上可以分爲以下五種

普通索引

普通索引是最基本的索引類型,唯一任務是加快對數據的訪問速度,沒有任何限制。創建普通索引時,通常使用的關鍵字是 INDEX 或 KEY

唯一性索引

唯一性索引是不允許索引列具有相同索引值的索引。如果能確定某個數據列只包含彼此各不相同的值,在爲這個數據列創建索引的時候就應該用關鍵字 UNIQUE 把它定義爲一個唯一性索引。創建唯一性索引的目的往往不是爲了提高訪問速度,而是爲了避免數據出現重複

主鍵索引

主鍵索引是一種唯一性索引,即不允許值重複或者值爲空,並且每個表只能有一個主鍵。主鍵可以在創建表的時候指定,也可以通過修改表的方式添加,必須指定關鍵字 PRIMARY KEY,注意一張表只能有一個主鍵

空間索引

空間索引主要用於地理空間數據類型 GEOMETRY

全文索引

全文索引只能在 VARCHAR 或 TEXT 類型的列上創建,並且只能在 MyISAM 存儲引擎

在實際使用中,索引通常被創建成單列索引組合索引

  • 單列索引就是索引只包含原表的一個列
  • 組合索引也稱爲複合索引或多列索引,相對於單列索引來說,組合索引是將原表的多個列共同組成一個索引

敲黑板:一個表可以有多個單列索引,但這些索引不是組合索引。一個組合索引實質上爲表的查詢提供了多個索引,以此來加快查詢速度。比如,在一個表中創建了一個組合索引(c1,c2,c3),在實際查詢中,系統用來實際加速的索引有三個:單個索引(c1)、雙列索引(c1,c2)和多列索引(c1,c2,c3)

索引注意事項和使用原則

注意事項

創建索引雖然可以提升Mysql的查詢性能,但是索引在使用的時候也不是爲所欲爲,越多越好,需要注意以下幾點

  • 索引的創建和維護需要消耗時間,這個時間會隨着數據量的增多而增加
  • 除了表中數據佔用控件,索引也需要佔用一定空間,如果要建立聚簇索引,那麼需要的空間就會更大
  • 當對錶中的數據進行增加、刪除和修改的時候,索引也要動態地維護,這樣就降低了數據的維護速度 

使用原則

  • 在經常需要搜索的列上建立索引,可以加快搜索的速度
  • 在作爲主鍵的列上創建索引,強制該列的唯一性,並組織表中數據的排列結構,在InnoDB存儲引擎,默認給主鍵添加索引
  • 在經常使用表連接的列上創建索引,這些列主要是一些外鍵,可以加快表連接的速度
  • 在經常需要根據範圍進行搜索的列上創建索引,因爲索引已經排序,所以其指定的範圍是連續的
  • 在經常需要排序的列上創建索引,因爲索引已經排序,所以查詢時可以利用索引的排序,加快排序查詢
  • 在經常出現在WHERE子句中的列上添加索引,加快條件的判斷速度

以下場景建議不要添加索引,添加了反而增加數據庫的壓力,產生負面影響

  • 對於那些在查詢中很少使用或參考的列不應該創建索引。因爲這些列很少使用到,所以有索引或者無索引並不能提高查詢速度。相反,由於增加了索引,反而系統要去維護和存儲,增大壓力
  • 對於那些只有很少數據值的列也不應該創建索引。因爲這些列的取值很少,例如用戶表的愛好列。查詢結果集的數據行佔了表中數據行的很大比例,增加索引並不能明顯加快檢索速度
  • 對於那些定義爲 TEXT、IMAGE 和 BIT 數據類型的列不應該創建索引。因爲這些列的數據量要麼相當大,要麼取值很少
  • 當修改性能遠遠大於檢索性能時,不應該創建索引。因爲修改性能和檢索性能是互相矛盾的。當創建索引時,會提高檢索性能,降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引,就是表中某個字段經常修改不要添加索引,因爲會動態維護!

 

路漫漫其修遠兮,吾將上下而求索 

本文若有任何看不懂,或者有錯誤的地方歡迎大家評論區留言,我時時關注哦

我是添添,用你勤勞的雙手點個贊吧,這將是我創作更多優質文章的動力!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章