索引
MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。
索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据。对于索引,会保存在额外的文件中。类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可。
1、索引选取类型
(1)越小的数据类型:越小的数据类型通常在磁盘、内存和CPU缓存中都需要更少的空间,处理起来更快。
(2)简单的数据类型:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。
(3)尽量避免NULL:应该指定列为NOT nuLL,在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。
2、不适合创建索引的列
(1)在查询中很少使用或者参考的列
既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
(2)数值结果种类少的列
因为本来结果集合就是相当于全表查询了,所以没有必要。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
(3)定义为text, image和bit数据类型的列
这是因为,这些列的数据量要么相当大,要么取值很少。
(4)修改性能远远大于检索性能时
这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。
(5)不会出现在where条件中的字段
3、适合创建索引的列
**(1)表的主键、外键必须有索引;**外键是唯一的,而且经常会用来查询。
(2)结果种类超过300的列。
(3)经常与其他表进行连接的连接字段。
(4)经常出现在Where子句中的字段。
加快判断速度,特别是大表的字段,应该建立索引,建立索引,一般用在select ……where f1 and f2 ,我们在f1或者f2上建立索引是没用的。只有两个使用联合索引才能有用
(5)经常用到排序的列上,因为索引已经排序。
(6)经常用在范围内搜索的列上创建索引,因为索引已经排序了,其指定的范围是连续的
4、索引优缺点
(1)优点
索引由数据库中一列或多列组合而成,其作用是提高对表中数据的查询速度与排序速度。
(2)缺点
创建和维护索引需要耗费时间。
索引会减慢写入速度。索引会降低 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过5个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
5、覆盖索引
覆盖索引是查找的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖。
当发起一个被索引覆盖的查询(也叫作索引覆盖查询)时,在EXPLAIN的Extra列可以看到“Using index”的信息
使用覆盖索引的几种优化场景:
查询字段在索引内部,覆盖索引生效,否则失效。
总结:覆盖索引沾边即可,where从头到尾检测
6、索引失效
(1)最佳左前缀原则
复合索引,头不匹配,索引失效;中间缺失,则只有前面生效。
有时mysql对简单有序的索引会自动优化where位置,从而使索引生效。
**(2)在索引列上做任何操作(**计算,函数,(自动/手动)类型转换)
(3)使用索引中范围条件右边的列,尽量使用覆盖索引
中间索引列用到了范围(>、<、like等),则后面的所以全失效(不包括本身)。
(4)防止失效,尽量使用覆盖索引(尽量不用)*
(5)除覆盖索引的like左模糊查询
a、使用select *
左模糊会使后面索引失效而右模糊则不会。
b、使用覆盖索引
全部生效
(6)is null 和 is not null
(7)字符串不加引号
字符串部分为数字时mysql会隐式转换成字符串,按(2)知索引失效。
(8)使用 or
(9)mysql查询优化器认为全表扫描速度大于使用索引
7、索引分类及操作
(1)分类
- 普通索引:仅加速查询
- 唯一索引:加速查询 + 列值唯一(可以有null)
- 主键索引:加速查询 + 列值唯一(不可以有null)+ 表中只有一个
- 组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
- 全文索引?:对文本的内容进行分词,进行搜索
(2)创建索引
--创建普通索引
CREATE INDEX index_name ON table_name(col_name);
--创建唯一索引
CREATE UNIQUE INDEX index_name ON table_name(col_name);
--创建普通组合索引
CREATE INDEX index_name ON table_name(col_name_1,col_name_2);
--创建唯一组合索引
CREATE UNIQUE INDEX index_name ON table_name(col_name_1,col_name_2);
--通过修改表结构创建索引
ALTER TABLE table_name
ADD INDEX index_name(col_name);
--创建表时直接指定索引
CREATE TABLE table_name (
ID INT NOT NULL,col_name VARCHAR (16) NOT NULL,INDEX index_name (col_name)
);
(3)删除索引
--直接删除索引
DROP INDEX index_name ON table_name;
--修改表结构删除索引
ALTER TABLE table_name
DROP INDEX index_name;
8、索引原理
9、实例
索引可用于查找或排序(可同时发挥作用)
(1)
第一个c1 c2 c3均生效,索引含模糊查询,type为range
第二个只有c1生效,type为ref