index索引
是什么
数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中的数据。索引的实现通常是使用B树以及其变种B+树。设置索引要付出代价的:一是增加了数据库的存储空间,二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。
优点
- 通过创建唯一性索引,可以保证数据库中表中每一行数据的唯一性
- 可以大大加快数据的检索速度,这也是创建索引最主要的原因
- 在使用分组或者排序子句进行查询时,能够显著加快速度
缺点
- 创建和维护索引需要耗费时间,这个时间随数据量的增加而增加
- 索引需要占用物理空间,会消耗空间资源
- 当对表中数据进行增加,删除和修改时,索引也要动态的维护,这样就降低了数据的维护速度
索引使用的场景
- 在需要经常搜索的列上,可以加快搜索的速度
- 在作为主键的列上,强制该列唯一性和组织表中数据的排列结构(主键会将【表】的数据格式转化成【索引(平衡树)】的格式)所以主键也可以理解为是一种索引
- 在经常用在连接的列上,这些列往往是一些外键,可以加快连接的速度。
- 在经常需要根据范围进行搜索的列上建索引,因为索引已经排序,其指定的范围是连续的。
- 在经常需要排序的列上建立索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间。
- 在经常使用在where子句中的列上建立索引,加快条件的判断速度。
不应该建立索引的列
- 在查询中很少使用的列不要建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
- 对于那些只有很少值的列也不要建立索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
- 对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。
- 当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少 索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。
什么情况下索引不会命中
- 如果条件中有or 即使条件中带索引也不会使用
注意:要想使用or,又要索引有效,需要在or中所有条件的列上加索引 - like查询以%开头,索引不会命中
有一种情况下,只查询索引列,才会用到索引,但是这种情况下跟是否使用%没有关系的,因为查询索引列的时候本身就用到了索引 - 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
- 查询条件中,在索引列上使用函数(+, - ,*,/), 这种情况下需建立函数索引
- 没有查询条件,或者查询条件没有建立索引
- 采用 not in, not exist
联合索引
在两个列或多个列上建立的索引称之为联合索引
利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引。复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。如果您知道姓,电话簿将非常有用;如果您知道姓和名,电话簿则更为有用,但如果您只知道名不姓,电话簿将没有用处。
所以说创建复合索引时,应该仔细考虑列的顺序。对索引中的所有列执行搜索或仅对前几列执行搜索时,复合索引非常有用;仅对后面的任意列执行搜索时,复合索引则没有用处。
为什么要使用联合索引
多个单列索引在多条件查询时优化器会选择最优索引策略,可能只用一个索引,也可能将多个索引都用上,但多个单列索引底层会建立多个B+索引树,比较占用空间,也会浪费一定的搜索效率,故如果只有多条件联合查询时,最好建立联合索引。如果条件经常性出现在一起,那么可以考虑将多字段索引升级为联合索引
最左前缀原则
顾名思义是最左优先,以最左边的为起点任何连续的索引都能匹配上,
注:如果第一个字段是范围查询需要单独建一个索引
注:在创建联合索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。这样的话扩展性较好,比如 userid 经常需要作为查询条件,而 mobile 不常常用,则需要把 userid 放在联合索引的第一位置,即最左边
联合索引本质
当创建(a,b,c)联合索引时,相当于创建了(a)单列索引,(a,b)联合索引以及(a,b,c)联合索引
想要索引生效的话,只能使用 a和a,b和a,b,c三种组合;当然,我们上面测试过,a,c组合也可以,但实际上只用到了a的索引,c并没有用到!
注:这个可以结合上边的 通俗理解 来思考!
索引的种类
聚集索引、非聚集索引、唯一索引
主键,唯一索引 聚集索引的关系
聚集索引是顺序结构与数据存储物理结构一致的一种索引,并且一个表的聚集索引只能有唯一的一条;数据库在创建主键同时,会自动建立一个唯一索引。
如果这个表之前没有聚集索引,同时建立主键时候没有强制指定使用非聚集索引,则建立主键时候,同时建立一个唯一的聚集索引
非聚集索引, 也就是我们平时经常提起和使用的常规索引。
非聚集索引和聚集索引一样, 同样是采用平衡树作为索引的数据结构。索引树结构中各节点的值来自于表中的索引字段, 假如给user表的name字段加上索引 , 那么索引就是由name字段中的值构成,在数据改变时, DBMS需要一直维护索引结构的正确性。如果给表中多个字段加上索引 , 那么就会出现多个独立的索引结构,每个索引(非聚集索引)互相之间不存在关联。 如下图
每次给字段建一个新索引, 字段中的数据就会被复制一份出来, 用于生成索引。 因此, 给表添加索引,会增加表的体积, 占用磁盘存储空间。
非聚集索引和聚集索引的区别在于, 通过聚集索引可以查到需要查找的数据, 而通过非聚集索引可以查到记录对应的主键值 , 再使用主键的值通过聚集索引查找到需要的数据,如下图
不管以任何方式查询表, 最终都会利用主键通过聚集索引来定位到数据, 聚集索引(主键)是通往真实数据所在的唯一路径。
有一种例外:联合索引
如果为一个索引指定两个字段, 那么这个两个字段的内容都会被同步至索引之中。
聚集索引,非聚集索引,覆盖索引 原理