数据库索引的本质是数据结构,这种数据结构能够帮助我们快速的获取数据库中的数据。
索引类型
- 唯一索引
看见名字我们就知道,唯一索引列中的值必须是唯一的。不过有一个例外,可以有且可以有多个Null。 - 普通索引
普通索引可以包括不止一列,一般把多个列组成的普通索引叫组合索引,也有把普通索引看成是只有一列的组合索引的。此外,在索引字符串时,可以只把前几位作为索引来提升效率。因为最左前缀,在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。 - 主键
主键必须唯一,不同的是不能有Null。而且一个表只能有一个主键。有很多人认为主键是唯一索引的一种,其实是不准确的。主键也可以是组合索引,只要组合的每条结果是唯一的。
注:
1.指定了AUTO_INCREMENT的列必须要建索引,不然会报错,主键,唯一键也是索引的一种不需要另外指定了。
2.mysql中执行查询时,对一张表只能使用一个索引,如果我们在例如lname,fname,age上分别单独建立索引,执行查询时,只能使用一个索引,mysql会选择一个最严格(获得结果集记录数最少)的索引(所以这里使用组合索引效率更高)。
在NAME加上索引
mysql> select * from creators where NAME = 'ABC';
mysql> alter table creators add index NAME (NAME);
mysql> select * from creators where NAME = 'ABC';
mysql> SHOW PROFILES;
设置索引
ALTER TABLE table_name ADD INDEX index_name (column_list)
ALTER TABLE table_name ADD UNIQUE (column_list)
ALTER TABLE table_name ADD PRIMARY KEY (column_list)
删除索引
DROP INDEX index_name ON talbe_name
ALTER TABLE table_name DROP INDEX index_name
ALTER TABLE table_name DROP PRIMARY KEY
第3条语句只在删除PRIMARY KEY索引时使用,如果没有创建PRIMARY KEY索引,但表具有一个或多个UNIQUE索引,则MySQL将删除第一个UNIQUE索引。
查看索引
mysql> show index from tblname;
mysql> show keys from tblname;
索引原则
最左前缀匹配原则
mysql> alter table creators add index cd_n_pn (CREATOR_DATE, NAME, PROFLIE_NAME);
mysql> select * from creators where CREATE_DATE = '2046-09-01' and NAME = 'ABC' and PROFLIE_NAME = 'DEF';
mysql> select * from creators where CREATE_DATE = '2046-09-01' and NAME = 'ABC';
mysql> select * from creators where CREATE_DATE = '2046-09-01' and PROFLIE_NAME = 'DEF';
mysql> select * from creators where NAME = 'ABC' and PROFLIE_NAME = 'DEF';
前三个查询会用到索引,最后一个查询因为没用到组合索引的最左列,所以不会用到索引而是遍历了所有的数据,这就是最左前缀匹配。
最左前缀匹配原则,是非常重要的原则,mysql会一直向右匹配(拿索引从左往右去匹配条件)直到遇到范围查询(>、<、between、like)就停止匹配,但第一个范围索引本身是可以使用索引的,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
再举一个例子:
假设你在表的state、city和zip数据列上建立了复合索引。索引中的数据行按照state/city/zip次序排列。这意味着,即使你在查询中只指定了state值,
或者指定state和city值,MySQL也可以使用这个索引。因此,这个索引可以被用于搜索如下所示的数据列组合:state, city, zip或state, city或state。MySQL不能利用这个索引来搜索没有包含在最左前缀的内容。例如,如果你按照city或zip或city,zip来搜索,就不会使用到这个索引。如果你搜索给定的state和zip(索引的1和3列),该索引也是不能用于这种组合值的,只会利用索引来查找匹配的state从而缩小搜索的范围。所以根据最左前缀原则,这个组合索引相当于创建了(state)单列索引,(state, city)组合索引以及(state, city, zip)组合索引。
选择区分度高的列作为索引
区分度:count(distinct col)/count(*),,表示字段不重复的比例,越接近1区分度越高,唯一键或主键的区分度就是1。
索引列不能参与计算
保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引。
尽量的扩展索引,不要新建索引
比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可
如何确定一个查询有没有走索引
MySQL中自带命令行工具 explain 来查看一个sql语句是否了索引
使用方式:
explain select * from tb_test;
关注的项:
- type : 查询access的方式,表的连接类型
index : 索引
full : 全表扫描
ref : 参照查询,也就是等值查询
range : 范围查询 - key : 本次查询最终选择使用哪个索引,NULL为未使用索引
- key_len : 选择的索引使用的前缀长度或者整个长度
- rows : 查询逻辑扫描过的记录行数
- extra : 额外信息,主要是指fetch data的具体方式
要点:
1.唯一索引:唯一索引列中的值必须是唯一的,但可以有多个Null。主键(没有Null),唯一键也是唯一索引的一种不需要另外指定了。
普通索引:普通索引可以包括不止一列,一般把多个列组成的普通索引叫组合索引。
2.AUTO_INCREMENT:对于innodb,指定了AUTO_INCREMENT的非主键列必须要在建表时显式建立索引,如果是组合索引,必须是组合索引的第一列,不然会报错。主键,唯一键也是索引的一种不需要另外指定了。且一个表只能有一个AUTO_INCREMENT属性。
3.添加索引:ALTER TABLE table_name ADD INDEX index_name (column_list)。
删除索引:DROP INDEX index_name ON talbe_name 或 ALTER TABLE table_name DROP INDEX index_name。
查看索引:show index from tblname。
4.最左前缀匹配原则:在查询中必须有索引最左列才会使用到这个索引,(拿索引从左往右去匹配条件,直到遇到范围查询 >、<、between、like 就停止匹配,但它本身可以使用索引。)所以如果都是=,则查询条件的顺序是可以变的。
5.用mysql自带的命令行工具 explain 来查看一个sql语句是否了索引,例如:explain select * from tb_test;