一庵佣、索引概述
索引(index)是幫助Mysql高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)(有序)。在數(shù)據(jù)之外撞芍,數(shù)據(jù)庫還維護者滿足特定算法的數(shù)據(jù)結(jié)構(gòu)秧了,這些數(shù)據(jù)結(jié)構(gòu)以某種方式引用(指向)數(shù)據(jù),這樣就可以在這些數(shù)據(jù)結(jié)構(gòu)實現(xiàn)高級查找算法序无,這種數(shù)據(jù)結(jié)構(gòu)就是索引验毡。
左邊是數(shù)據(jù)表,一共7條數(shù)據(jù)帝嗡,最左側(cè)是(0x07...)這些是數(shù)據(jù)的物理地址(邏輯上相鄰的數(shù)據(jù)晶通,在磁盤記錄中也不一定是物理相鄰的)。
在沒建立索引的情況下
:我們想要獲取col2中的值需要一條條的便利尋找哟玷,如果尋找值為3的數(shù)據(jù)狮辽,相當(dāng)于做了一次整張表掃描
建立索引的情況下
:維護右側(cè)二叉查找樹,每個節(jié)點包含索引鍵值和指向?qū)?yīng)數(shù)據(jù)的記錄物理地址的指針巢寡,再獲取值為3的數(shù)據(jù)時喉脖,根據(jù)索引,只需要三步就能找到對應(yīng)的數(shù)據(jù)抑月,不需要掃描全表
二树叽、索引的優(yōu)劣
優(yōu)勢:
1)類似書籍目錄的索引,提高了數(shù)據(jù)的檢索效率谦絮,降低了數(shù)據(jù)庫的IO成本
2)通過索引對數(shù)進行排序题诵,降低了數(shù)據(jù)的排序成本,降低了CPU的消耗
劣勢:
1)實際索引也是一張表层皱,該表保存了主鍵和索引字段性锭,并指向?qū)嶓w類的字段,所以索引也需要占用空間
2)雖然索引大大提高了查詢效率叫胖,但同時也降低了更新表的速度草冈,如對表進行Insert,update,delete操作時,Mysql不僅需要更新數(shù)據(jù)臭家,同時還要保存索引文件每次更新添加了索引列的字段以及調(diào)整因為更新所帶來的鍵值變化后的索引信息
三疲陕、索引結(jié)構(gòu)
索引實在Mysql的存儲引擎中實現(xiàn)的,所以每一種引擎的索引結(jié)構(gòu)都不一定相同钉赁,同時也不是所有的搜索引擎支持所有的索引結(jié)構(gòu),Mysql為我們提供了一下四種索引結(jié)構(gòu)
1)BTREE索引:最常見的索引類型携茂,大部分搜索引擎都支持B樹索引
2)Hash索引:只有Memory引擎支持 你踩, 使用場景簡單
3)R-tree 索引(空間索引):空間索引是MyISAM引擎的一個特殊索引類型,主要用于地理空間數(shù)據(jù)類型,通常使用較少
4)Full-text (全文索引) :全文索引也是MyISAM的一個特殊索引類型带膜,主要用于全文索引吩谦,InnoDB從Mysql5.6版本開始支持全文索引
ps:這里暫不做索引結(jié)構(gòu)的說明
四、索引分類
1)單值索引:即一個索引包含單個列膝藕,一個表可以有多個單列索引
2)唯一索引:索引列的值必須唯一式廷,但允許為空
3)復(fù)合索引:既一個列包含多個索引
五、創(chuàng)建索引
1)創(chuàng)建數(shù)據(jù)庫及表
# 創(chuàng)建 demo_01
CREATE DATABASE demo_01 DEFAULT charset=utf8mb4;
# 使用 數(shù)據(jù)庫
USE demo_01;
#創(chuàng)建表
CREATE TABLE `city` (
`city_id` int(11) NOT NULL AUTO_INCREMENT,
`city_name` varchar(50) NOT NULL,
`country_id` int(11) NOT NULL,
PRIMARY KEY (`city_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `city` (`city_id`, `city_name`, `country_id`) values(1,'西安',1);
insert into `city` (`city_id`, `city_name`, `country_id`) values(2,'NewYork',2);
insert into `city` (`city_id`, `city_name`, `country_id`) values(3,'北京',1);
insert into `city` (`city_id`, `city_name`, `country_id`) values(4,'上海',1);
insert into `country` (`country_id`, `country_name`) values(1,'China');
insert into `country` (`country_id`, `country_name`) values(2,'America');
insert into `country` (`country_id`, `country_name`) values(3,'Japan');
insert into `country` (`country_id`, `country_name`) values(4,'UK');
2)創(chuàng)建索引
創(chuàng)建索引語法:
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
[USING index_type]
ON tbl_name(index_col_name,...)
index_col_name : column_name[(length)][ASC | DESC]
示列:為city表中的city_name 創(chuàng)建索引
create index idx_city_name on city(city_name);
3)查看索引
查看索引語法
show index from tab_name
示列:查看city_name表中的索引
show index from city_name
ps:city_id作為自增長主鍵芭挽,mysql會自動幫我創(chuàng)建索引
4)刪除索引
刪除索引語法
DROP INDEX index_name ON tbl_name;
示列:刪除我們我們剛剛創(chuàng)建的idx_city_name索引
drop index idx_city_name from city;
5)ALTER命令創(chuàng)建索引
添加一個主鍵滑废,這意味著索引值必須是唯一的,且不能為NULL
alter table tb_name add primary key(column_list);
創(chuàng)建索引的值必須是唯一的(除了NULL外袜爪,NULL可能會出現(xiàn)多次)
alter table tb_name add unique index_name(column_list);
普通索引蠕趁, 索引值可以出現(xiàn)多次。
alter table tb_name add index index_name(column_list);
指定了索引為FULLTEXT辛馆, 用于全文索引
alter table tb_name add fulltext index_name(column_list);
6)創(chuàng)建復(fù)合索引
CREATE INDEX idx_name_email_status ON tb_seller(NAME,email,STATUS);
就相當(dāng)于
對name 創(chuàng)建索引 ;
對name , email 創(chuàng)建了索引 ;
對name , email, status 創(chuàng)建了索引 ;
六俺陋、索引的設(shè)計原則
1)對查詢頻次較高且數(shù)據(jù)量比較大的表建立索引
2)索引字段最佳候選列應(yīng)當(dāng)從where子語句中條件中提取,如果where子語句條件過多昙篙,那么應(yīng)當(dāng)挑選最常用腊状,過濾效果最好的的列的組合
3)使用唯一索引,區(qū)分度越高苔可,使用索引的效率越高
4)索引可以有效的提升查詢數(shù)據(jù)的效率缴挖,但索引數(shù)量不是多多益善,索引越多硕蛹,維護索引的代價自然也就水漲船高醇疼。對于插入、更新法焰、刪除等DML操作比較頻繁的表來說秧荆,索引過多,會引入相當(dāng)高的維護代價埃仪,降低DML操作的效率乙濒,增加相應(yīng)操作的時間消耗。另外索引過多的話卵蛉,MySQL也會犯選擇困難病颁股,雖然最終仍然會找到一個可用的索引,但無疑提高了選擇的代價
5)使用短索引傻丝,索引創(chuàng)建之后也是使用硬盤來存儲的甘有,因此提升索引訪問的I/O效率,也可以提升總體的訪問效率葡缰。假如構(gòu)成索引的字段總長度比較短亏掀,那么在給定大小的存儲塊內(nèi)可以存儲更多的索引值忱反,相應(yīng)的可以有效的提升MySQL訪問索引的I/O效率
6)利用最左前綴,N個列組合而成的組合索引滤愕,那么相當(dāng)于是創(chuàng)建了N個索引温算,如果查詢時where子句中使用了組成該索引的前幾個字段,那么這條查詢SQL可以利用組合索引來提升查詢效率