索引的目的是提高查询效率。
[En]
The purpose of index is to improve query efficiency.
一 索引分类
1、普通索引 index
加速查询
2、唯一索引
2.1、主键索引 primary key
加速查询+约束(不为空且唯一)
2.2、唯一索引 unique
加速查询+约束(唯一)
3、联合索引
— index(id,name) 联合普通索引
— primary key(id,name) 联合主键索引
— unique(id,name) 联合唯一索引
4、全文索引 fulltext
它在搜索长篇文章时效果最好。
[En]
It works best when searching for long articles.
5、空间索引 spatial
二 索引类型
当我们创建索引时,我们可以为它指定索引类型,它可以分为两类。
[En]
When we create an index, we can specify the index type for it, which can be divided into two categories.
1、hash类型
查询单条快,范围查询慢
2、btree类型 B+树
b+树,层级越多,数据量指数级增长
不同的存储引擎支持的索引类型也不一样
InnoDB 支持事务,支持行级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;
MyISAM 不支持事务,支持表级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;
Memory 不支持事务,支持表级别锁定,支持 B-tree、Hash 等索引,不支持 Full-text 索引;
NDB 支持事务,支持行级别锁定,支持 Hash 索引,不支持 B-tree、Full-text 等索引;
Archive 不支持事务,支持表级别锁定,不支持 B-tree、Hash、Full-text 等索引;
三 创建\删除索引的语法
1、创建索引
在创建表时就添加索引 及 注意事项
create table TABLE_NAME(
id int, # 可以添加primary key
id int index, # 不可以这么添加索引,因为index是普通索引,没有约束一说,所以不能像主键索引和唯一索引那样在定义字段的时候加索引
name char(20),
age int,
email varchar(30)
primary key(id) # 也可以为主键这样添加索引
index(id) # 虽然不能在定义字段的同时添加普通索引,但是通过这种方式为字段添加普通索引
在创建表之后添加索引
create index name on TABLE_NAME(name); # 添加普通索引
create unique age on TABLE_NAME(age); # 添加唯一索引
alter table TABLE_NAME add primary key(id); # 添加主键索引,也就是给id字段增减一个主键约束
create index name on TABLE_NAME(id,name); # 添加普通联合索引
2、删除索引
drop index name on TABLE_NAME; # 删除普通索引
drop index age on TABLE_NAME; # 删除唯一索引,就和普通索引一样,不用在index前加unique就可以删除
alter table TABLE_NAME drop promary key; # 删除主键(因为它添加的时候是按照alter来增加的,那么我们也用alter来删)
四 测试索引
1、准备表
create table TABLE_NAME(
id int,
name varchar(20),
gender char(6),
email varchar(50)
);
2、创建存储过程,实现批量插入记录
delimiter $$ #声明存储过程的结束符号为$$
create procedure auto_insert1()
BEGIN
declare i int default 1;
while(i
3、查看存储过程
show create procedure auto_insert1\G
4、调用存储过程
call auto_insert1();
五 正确使用索引
1、覆盖索引
分析
select * from TABLE_NAME where id=123;
该sql命中了索引,但未覆盖索引。
利用id=123到索引的数据结构中定位到该id在硬盘中的位置,或者说再数据表中的位置。
但是我们select的字段为*,除了id以外还需要其他字段,这就意味着,我们通过索引结构取到id还不够,
还需要利用该id再去找到该id所在行的其他字段值,这是需要时间的,很明显,如果我们只select id,
就减去了这份苦恼,如下
select id from TABLE_NAME where id=123;
这条就是覆盖索引了,命中索引,且从索引的数据结构直接就取到了id在硬盘的地址,速度很快
2、联合索引
create index ne on s1(name,email);#组合索引
3、索引合并
索引合并:把多个单列索引合并使用
分析:
我们可以使用索引合并来解决综合指数可以做的所有事情,例如
[En]
We can use index merging to solve all the things that a composite index can do, such as
create index ne on s1(name,email);#组合索引
我们完全可以单独为name和email创建索引
组合索引可以命中:
select * from s1 where name=’egon’ ;
select * from s1 where name=’egon’ and email=’adf’;
索引合并可以命中:
select * from s1 where name=’egon’ ;
select * from s1 where email=’adf’;
select * from s1 where name=’egon’ and email=’adf’;
乍一看好像索引合并更好了:可以命中更多的情况,但其实要分情况去看,如果是name=’egon’ and email=’adf’,
合并索引的效率高于合并索引的效率。如果是单一条件搜索,则使用索引合并更为合理。
[En]
Then the efficiency of combined indexes is higher than that of index merging. If it is a single conditional search, it is more reasonable to use index merging.
4、添加索引遵循原则
1、最左前缀匹配原则,非常重要的原则,
create index ix_name_email on s1(name,email,)
- 最左前缀匹配:必须按照从左到右的顺序匹配
select * from s1 where name=’egon’; #可以
select * from s1 where name=’egon’ and email=’asdf’; #可以
select * from s1 where email=’alex@oldboy.com’; #不可以
mysql会一直向右匹配直到遇到范围查询(>、
Original: https://www.cnblogs.com/ganguixu/p/15798198.html
Author: 干桂旭
Title: Mysql 索引
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/507874/
转载文章受原作者版权保护。转载请注明原作者出处!