数据库索引

数据库索引概念:索引是对数据库中一列或多列的值进行排序的一种结构,使用索引可以快速访问数据库表中的特定信息,而不必扫描整个数据库。索引就是一种满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。

索引的优缺点

优点:

1、可以大大加快数据的检索速度。

2、通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

3.可以加快表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。

4、在使用分组和排序字句进行数据检索时,同样可以显著减少查询中分组和排序的时间。

5、通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

缺点:

1、创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。

2、索引需要占物理空间,出了数据表要转矩数据空间外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。

3、当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这就降低了数据的维护速度。

哪些列适合创建索引?

1、经常需要搜索的列

2、作为主键的列,强制该列的唯一性和组织表中数据的排序结构。

3.经常用来连接的列,主要是一些外键,可以加快连接速度

4、经常需要排序的列,因为索引已经排序,这样查询可以利用索引的排序加快查询速度

5、经常使用在where字句中的列,可以加快条件的判断速度

哪些列不适合创建索引?

1、在查询中很少使用或者参考的列

2、数值很少的列,例如性别,在查询结果中,结果集的数据行占了表中数据行的很大比例

3、定义为text、image、bit数据类型的列不应该添加索引,因为这些列要么数据量相当大,要么取值相当少。

索引类型

1、唯一索引 UNIQUE:此索引的每一个索引值只对应唯一的数据记录,对于单列唯一性索引,这保证单列不包含重复的值,对于多列唯一性索引,保证多个值的组合不重复。

2、主键索引 primary key:数据库表经常有一列或多列组合,其值唯一标识表中的每一行,该列称为表的主键。在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每一个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。

3、聚集索引(聚簇索引) cluster:在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑(索引)顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。

索引的实现方式

1、B+树

我们经常听到B+树就是这个概念,用这个树的目的和红黑树差不多,也是为了尽量保持树的平衡,当然红黑树是二叉树,但B+树就不是二叉树了,节点下面可以有多个子节点,数据库开发商会设置子节点数的一个最大值,这个值不会太小,所以B+树一般来说比较矮胖,而红黑树就比较瘦高了。

关于B+树的插入,删除,会涉及到一些算法以保持树的平衡,这里就不详述了。ORACLE的默认索引就是这种结构的。如果经常需要同时对两个字段进行AND查询,那么使用两个单独索引不如建立一个复合索引,因为两个单独索引通常数据库只能使用其中一个,而使用复合索引因为索引本身就对应到两个字段上的,效率会有很大提高。

2 散列索引

第二种索引叫做散列索引,就是通过散列函数来定位的一种索引,不过很少有单独使用散列索引的,反而是散列文件组织用的比较多。
散列文件组织就是根据一个键通过散列计算把对应的记录都放到同一个槽中,这样的话相同的键值对应的记录就一定是放在同一个文件里了,也就减少了文件读取的次数,提高了效率。
散列索引呢就是根据对应键的散列码来找到最终的索引项的技术,其实和B树就差不多了,也就是一种索引之上的二级辅助索引,我理解散列索引都是二级或更高级的稀疏索引,否则桶就太多了,效率也不会很高

3 位图索引
    位图索引是一种针对多个字段的简单查询设计一种特殊的索引,适用范围比较小,只适用于字段值固定并且值的种类很少的情况,比如性别,只能有男和女,或者级别,状态等等,并且只有在同时对多个这样的字段查询时才能体现出位图的优势。
位图的基本思想就是对每一个条件都用0或者1来表示,如有5条记录,性别分别是男,女,男,男,女,那么如果使用位图索引就会建立两个位图,对应男的10110和对应女的01001,这样做有什么好处呢,就是如果同时对多个这种类型的字段进行and或or查询时,可以使用按位与和按位或来直接得到结果了。

 使用索引的注意事项

1、越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和CPU缓存中都需要更少的空间,处理起来更快。
2、简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。在MySQL中,应该用内置的日期和时间数据类型,而不是用字符串来存储时间;以及用整型数据类型存储IP地址。
3、尽量避免NULL:应该指定列为NOT NULL,除非你想存储NULL。在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值。

4、索引不会包含有NULL值的列。

索引失效的原因

1、没有查询条件或者查询条件没有建立索引

2、在查询条件上没有使用引导列(组合索引中的第一列)

3、查询的数量是大表的大部分,应该是30%以上。

4、索引本身失效

5、查询条件使用函数在索引列上

6、对小表查询

7、提示不使用索引

8、统计数据不真实

9、隐式转换导致索引失效

10、对索引列进行运算导致索引失效

11、like “%_“ 百分号在前,如果百分号在后索引不会失效

12、使用复合索引时没有使用第一列

13、字符型字段为数字时在where条件里不添加引号. 

错误的例子:select * from test where tu_mdn=13333333333; 
正确的例子:select * from test where tu_mdn='13333333333'; 

14、B-tree索引 is null不会走,is not null会走,位图索引 is null,is not null 都会走 

15、NOT IN和<>操作都不会使用索引将进行全表扫描。NOT IN可以NOT EXISTS代替,id<>3则可使用id>3 or id<3来代替

mysql查看索引使用情况

show status like ‘Handler_read%’;
大家可以注意:
handler_read_key:这个值越高越好,越高表示使用索引查询到的次数
handler_read_rnd_next:这个值越高,说明查询低效
原文地址:https://www.cnblogs.com/mingyao123/p/7357346.html