MySQL 索引
內容主要摘抄自《MySQL5.7從入門到精通》
索引是對數據庫表中的一列或多列進行排序的一種數據結構,使用索引可以提高數據庫中特定數據的查詢速度。
一、索引含義和特點
索引是一個單獨的、存儲在磁盤上的數據庫結構,它們包含着對數據表里所有記錄的引用指針。
mysql 中索引存儲類型有兩種:BTREE 和 HASH,具體和表的存儲引擎相關;MyISAM 和 InnoDB 存儲引擎只支持 BTREE 索引;MEMORY/HEAP 存儲引擎可以支持 HASH 和 BTREE 索引。
二、索引分類
-
普通索引和唯一索引
普通索引:定義的索引列運行有空值和重復值。
唯一索引:索引列的值必須唯一,允許有空值。 -
單列索引和組合索引
單列索引:一個索引只包含單列。
組合索引:在表的多個字段組合上創建的索引,使用組合索引時遵循最左前綴集合,只有查詢條件中使用了這些字段的左邊字段,索引才會被使用。 -
全文索引
全文索引類型為 FULLTEXT,在定義索引的列上支持值的全文查找,允許索引列插入重復值和空值。全文索引可以在字符或文本類型的列上創建,mysql 中只有 MyISAM 存儲引擎支持全文索引。
-
空間索引
mysql 空間數據類型有四種:GEOMETRY、POINT、LINESTRING 和 POLYGON。空間索引是對空間數據類型的字段建立的索引,創建空間索引的列必須聲明為 NOT NULL。
三、索引設計原則
-
索引並非越多越好
一個表中若有大量索引,會占用磁盤空間,也會影響 insert、delete、update 等語句的性能,因為表中數據更改時,索引也會進行調整和更新。
-
索引中的列盡可能的少
對經常查詢的字段應該創建索引,但要避免添加不必要的字段。
-
對數據量小的表不要使用索引
由於數據較少,查詢的花費的時間可能比遍歷索引的時間還要短,可能不會產生優化效果。
-
在不同值較多的列上建立索引
例如性別字段上只有“男”,“女”,“其他”,三個不同值,若在性別列上建立索引,可能不但不會提高查詢效率,反而會嚴重降低數據更新速度。
四、查詢表中索引
SHOW INDEX FROM test;
一般查詢結果顯示的是表格形式,在查詢語句后加上 \G 可以將查詢結果縱向顯示。
上圖顯示 id 為唯一索引。
五、創建索引
官網參考手冊(5.7)-- CREATE INDEX Syntax
1. 創建表時創建索引
創建名為 idx_name 的普通索引,對唯一性沒有限制
CREATE TABLE test2 (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
num int(11) NOT NULL DEFAULT 0,
created_at timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX idx_name(name(5))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INDEX idx_name(name(5))
上面語句指的是截取字段 name 前5個字符作為索引,也就是說每條記錄的name字段的值的前5個字符不能出現重復,否則在使用 INSERT 時會出現 “Duplicate” 錯誤。
2. 使用 ALTER TABLE 語句
ALTER TABLE test2 ADD INDEX idx_name(name(5));
3. 使用 CREATE INDEX 語句
CREATE INDEX idx_name ON test2(name(5));
六、刪除索引
1. 使用 ALTER TABLE 刪除
ALTER TABLE test2 DROP INDEX idx_name;
2. 使用 DROP INDEX 刪除
DROP INDEX idx_name ON test2;
七、索引名稱規范
-
普通索引
"idx_" 前綴加上字段名稱,eg: idx_name
-
唯一索引
"uniq_"前綴加上字段名稱,eg: uniq_name
八、索引長度限制
長度不超過767bytes,聯合索引長度不超過3072bytes。
於InnoDB索引長度限制的tips
mysql innodb存儲與索引的總結
九、什么情況適合建索引?
十、小測試
創建一個表,字段如下:
批量插入80萬條數據,name長度為30字符左右
創建索引花了3秒多,創建索引后同一條查詢語句,執行時間加快的差不多770倍,對比還是很明顯的