索引是一个排序的列表,列表当中存储的时索引的值和包含这个值的数据所在行的物理地址(类似于C语言的链表通过指针指向数据记录的内存地址)。
索引的副作用
有索引,数据会先进行索引查询,然后定位数据,索引使用不当,反而会增加数据库的负担
1、B-树索引,又叫Btree树形结构的索引,也是大部分数据库的默认索引类型。
基于这种树形数据结构,表中的每一行都会在索引上有一个对应值。因此,在表中进行数据查询时,可以根据索引值一步一步定位到数据所在的行。
2、哈希索引,散列索引,把任意长度的输入,通过散列算法变换成固定长度的输出,该输出就是散列值,散列值分别对应数据里的列和行。
查看表的索引
show index from 表名;
修改索引类型
alter table 表名 engine=INNODB/MEMORY;
最基本的索引类型,没有唯一性之类的限制
直接创建:
create index 索引名 on 表名 (列名[(length)]);
#(列名(length)):length是可选项
如果忽略length的值,则使用整个列的值作为索引
如果指定,使用列的前length个字符来创建索引
#索引名建议以“_index”结尾
修改表方式创建:
alter table 表名 add index 索引名 (列名);
创建表时指定:
create table 表名 (
...
index 索引名 (列名)
);
与普通索引类似,但区别是唯一索引列的每个值都唯一
唯一索引允许有空值(注意和主键不同)
如果是用组合索引创建,则列值的组合必须唯一
添加唯一键将自动创建唯一索引
直接创建:
create unique index 索引名 on 表名 (列名);
修改表方式创建:
alter table 表名 add unique 索引名 (列名);
创建表时指定:
create table 表名 (
...
unique 索引名 (列名)
);
是一种特殊的唯一索引,必须指定为“PRIMARY KEY”
一个表只能有一个主键,不允许有空值
添加主键将自动创建主键索引
创建表时指定:
create table 表名 (
...
primary key (列名)
);
修改表方式创建:
alter table 表名 add primary key (列名);
适合在进行模糊查询的时候使用,可用于在一篇文章中检索文本信息
直接创建:
create fulltext index 索引名 on 表名 (列名);
修改表方式创建:
alter table add fulltext 索引名 (列名);
创建表时指定:
CREATE TABLE 表名 (
...
索引名 (列名)
);
#数据类型可以为CHAR、VARCHAR或者TEXT
使用全文索引查询:
select * from 表名 where match(列名) against('查询内容');
select * from 表名 where 列名 like '查询内容';
指定一个索引名,一个索引名对应多个列名
可以是单列上创建的索引,也可以是在多列上创建的索引
需要满足最左原则,因为 select 语句的 where 条件是依次从左往右执行的,所以在使用 select 语句查询时 where 条件使用的字段顺序必须和组合索引中的排序一致,否则索引将不会生效
直接创建:
create index 索引名 on 表名(列名1,列名2,列名3,...);
修改表的方式创建:
alter table 表名 add index 索引名 (字段1,字段2,字段3,...);
创建表时指定:
CREATE TABLE 表名 (
...
index 索引名 (列名1,列名2,列名3,...),
);
select 查询时 where 语句中的条件字段 要与组合索引的字段排列顺序一致(最左原则)
select * from 表名 where 列名1='...' and 列名2='...' and 列名3='...';
explain select...
示例:
create table test (
id int(4) primary key,
name varchar(10),
cardid int(18) not null,
phone int (11) not null,
unique index name_cardid_phone (name,cardid,phone) #都是唯一值的联合索引
);
mysql机制:默认会找最短的索引列
联合索引,从左到右侧开始,不能跳过索引,否则索引会失效
字符串不加引号索引也会失效
使用or语句索引一定失效,使用or作为条件,mysql无法同时使用多个索引
最左前缀法则 : 如果是联合索引,查询从索引的最左侧开始,不跳过其他索引. 如果跳过,则索引失效
create index index_name on user(name,status,address);
select * from user where name = ? and status = ? and address = ? (全部索引有效)
select * from user where status = ? (索引失效)
select * from user where name = ? and status = ? (两个索引有效)
select * from user where name = ? and address = ? (第一个索引有效, 第二个失效)
select * from user where status = ? and address = ? (索引失效)
直接删除索引:
drop index 索引名 on 表名;
修改表方式删除索引:
alter table 表名 drop index 索引名;
删除主键索引:
alter table 表名 drop primary key;