索引是一个排序的列表,列表当中存储的时索引的值和包含这个值的数据所在行的物理地址(类似于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;