一,什么是索引

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。
可以得到索引的本质:索引是数据结构。
索引的目的在于提高查询效率,可以类比字典。
可以简单理解为“排好序的快速查找数据结构”。
下图就是一种可能的索引方式
image.png
为了加快Col2的查找速度,可以维护个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录的物理地址的指针,这样就可以运用二叉树在一定的复杂度内获取到对应数据,从而快速的检索出符合条件的记录。
索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上。

二,索引的优缺

1优势

1,提高数据检索的效率,降低数据库的IO成本。
2,通过索引对数据进行排序,降低数据排序的成本,降低了CPU的消耗。

2,劣势

1,索引也是表,该表保存了主键与索引字段,并指向实体表的记录,索引索引列也是要占用空间的。
2,虽然索引大大提高了查询速度,但同时却会降低更新表的更新速度,因为每次对数据的调整都会带来对键值变化后的索引信息的改变。

三,索引的分类

1,单列索引

一个索引只包含单个列,但一个表中可以有多个单列索引。

1.1普通索引

MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。

1.2唯一索引

索引列中的值必须是唯一的,但是允许为空值。

  1. #随表一起建索引:
  2. CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200),
  3. PRIMARY KEY(id),
  4. KEY (customer_name),
  5. UNIQUE (customer_no)
  6. );
  7. #建立 唯一索引时必须保证所有的值是唯一的(除了null),若有重复数据,会报错。
  8. #单独建唯一索引:
  9. CREATE UNIQUE INDEX idx_customer_no ON customer(customer_no);
  10. #删除索引:
  11. DROP INDEX idx_customer_no on customer ;

1.3主键索引

是一种特殊的唯一索引,不允许有空值。
语法:

  1. #随表一起建索引:
  2. CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200),
  3. PRIMARY KEY(id)
  4. );
  5. #使用AUTO_INCREMENT关键字的列必须有索引(只要有索引就行)。
  6. CREATE TABLE customer2 (id INT(10) UNSIGNED,customer_no VARCHAR(200),customer_name VARCHAR(200),
  7. PRIMARY KEY(id)
  8. );
  9. #单独建主键索引:
  10. ALTER TABLE customer add PRIMARY KEY customer(customer_no);
  11. #删除建主键索引:
  12. ALTER TABLE customer drop PRIMARY KEY ;
  13. #修改建主键索引:
  14. #必须先删除掉(drop)原索引,再新建(add)索引

2,复合索引

即一个索引包含多个列
在数据库操作期间,复合索引比单值索引所需要的开销更小(对于相同的多个列建索引)
当表的行数远大于索引列的数目时可以使用复合索引
语法:

  1. #随表一起建索引:
  2. CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200),
  3. PRIMARY KEY(id),
  4. KEY (customer_name),
  5. UNIQUE (customer_name),
  6. KEY (customer_no,customer_name)
  7. );
  8. #单独建索引:
  9. CREATE INDEX idx_no_name ON customer(customer_no,customer_name);
  10. #删除索引:
  11. DROP INDEX idx_no_name on customer ;

使用复合索引时,遵循最左前缀集合
例如你这个联合索引是state/city/zipCode
那么state就是第一关 city是第二关, zipCode就是第三关
你必须匹配了第一关,才能匹配第二关,匹配了第一关和第二关,才能匹配第三关
你不能直接到第二关的
索引的格式就是第一层是state,第二层才是city
索引是因为B+树结构 所以查找快 如果单看第三列 是非排序的。
多列索引是先按照第一列进行排序,然后在第一列排好序的基础上再对第二列排序,如果没有第一列的话,直接访问第二列,那第二列肯定是无序的,直接访问后面的列就用不到索引了。

3,全文索引

即为全文索引,目前只有MyISAM引擎支持。其可以在CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不过目前只有 CHAR、VARCHAR ,TEXT 列上可以创建全文索引。

全文索引并不是和MyISAM一起诞生的,它的出现是为了解决WHERE name LIKE “%word%”这类针对文本的模糊查询效率较低的问题。


1. MySQL 5.6 以前的版本,只有 MyISAM 存储引擎支持全文索引;
2.MySQL 5.6 及以后的版本,MyISAM 和 InnoDB 存储引擎均支持全文索引;

4,空间索引

空间索引是对空间数据类型的字段建立的索引,MySQL中的空间数据类型有四种,GEOMETRY、POINT、LINESTRING、POLYGON。在创建空间索引时,使用SPATIAL关键字。
要求引擎为MyISAM,创建空间索引的列,必须将其声明为NOT NULL。

四,索引的创建删除

1,创建索引

  1. --创建普通索引
  2. CREATE INDEX index_name ON table_name(col_name);
  3. --创建唯一索引
  4. CREATE UNIQUE INDEX index_name ON table_name(col_name);
  5. --创建普通组合索引
  6. CREATE INDEX index_name ON table_name(col_name_1,col_name_2);
  7. --创建唯一组合索引
  8. CREATE UNIQUE INDEX index_name ON table_name(col_name_1,col_name_2);

2,通过修改表结构创建索引

  1. ALTER TABLE table_name ADD INDEX index_name(col_name);

3. 创建表时直接指定索引

  1. CREATE TABLE table_name (
  2. ID INT NOT NULL,
  3. col_name VARCHAR (16) NOT NULL,
  4. INDEX index_name (col_name)
  5. );

4. 删除索引

  1. --直接删除索引
  2. DROP INDEX index_name ON table_name;
  3. --修改表结构删除索引
  4. ALTER TABLE table_name DROP INDEX index_name;

五,创建索引的时机

1,什么情况下适合创建索引


1. 主键自动建立唯一索引。
1. 频繁作为条件查询的字段。
1. 查询中与其他表关联的字段,比如外键。
1. 单键/组合索引对比,组合索引性价比更高。
1. 查询中需要排序的字段。
1. 查询中需要统计或分组的字段。

2,什么情况下不适合创建索引


1. 表记录太少,比如只有几行,几百行记录。
1. 经常增、删、改的表或字段。
1. where条件里用不到的字段。
1. 过滤性不好的字段。(过滤性不好表示不能唯一定位一条记录或者每次定位记录行数太多,比如性别。而身份证号过滤性就很好。)

六,查看索引是否生效

链接——->EXPLAIN