【SQL 必知必会】性能篇 04.深入浅出索引(一)

索引在SQL优化中占很大的比重,好的索引能提高查询效率。索引好比书本的目录,通过目录我们可以在海量的数据中很快的定位到要查找的内容,如果不加索引,则是通过表一个个扫描的,查询效率极低,但是加了索引一定好么?什么情况下我们不使用索引呢?我们常见的索引类型都有哪些?索引的知识点较多,篇幅可能不止这一篇哦!

1. 思考

  • 索引为什么快,索引常见的模型有哪些?
  • 索引是万能的么,加索引一定快么?
  • 什么情况下不使用索引 常见的索引种类有哪些?

2.索引为什么这么快(mysql为什么选择的B+Tree)

实现索引的方式有很多,是常见的有哈希、有序数组、搜索树三种。

哈希

哈希:是一种键值对(key-value)的存储结构,通过一定的哈希算法,存储数据,当查找数据的时候通过key,可直接找到对应的值Value,此时会存在哈希冲突,所谓的哈希冲突就是多个key经过哈希算法那得到同一个值,此时需要在存放value值的位置后面拉出一个链表,通过哈希函数算得出N以后,然后顺序遍历该链表,但是存在一个问题,链表不是有序的,如果哈查找某区间的数据 ,则会将所有的链表都遍历一遍,查询效率是很低的,我们可以得出,hash这种数据结构模型适合于No SQL 数据库,例如Redis等 在关系型数据库中,也只适合等值查询,SQL语句如下所示:

select * from user where id =001;

在这里插入图片描述
有序数组

有序数组:如果进行范围查询的话,我们可以将上述链表改为有序数组,数组是一块连续的内存空间,这样可以查询一个区间的数据就会变得很快,也可以通过二分法查找具体的某一个数据,时间复杂度为O(logn)。问题来了,如果在数组总进行数据的插入和删除操作,可能会对数据进行移动,插入和删除数据会成本就会很高,时间复杂度为O(n)。所以有序数组适合于静态的存储引擎,例如经常存放不变的历史数据的数据仓库。

二叉树

二叉树:每个节点最多有两个后继节点,且右子树的值大于左子树的值,这样我们可以通过二分法查找我们需要的数据,此时时间复杂度为O(logn)。可见查询速率是树的高度成反比,后来引入的B-Tree,以及B+Tree等,稍后我们会具体详解B+Tree。

3. 索引是万能的么?什么情况下不使用它!

1. 数据量少的时候不使用索引

当数据量很少的时候全表扫描的速度,大于有索引的速度。我们知道计算机存储的基本单位是页,一个页中可能是多行数据记录,当进行 I/O 操作的时候,是以页为单位对数据进行的加载。我们极致的想一下,如果数据量只有一条,此时如果加索引,先查找索引,然后在根据索引找数据,不加索引则直接通过全表扫描查找数据。那么数据量多少是少呢?一般少于1000行数据时不用加索引的。

2. 数据重复度高于10% 的时候不适用索引。

扫描二维码关注公众号,回复: 10512707 查看本文章

例如数据表中性别字段,除了男性就是女性,数据重复度为50%。那么这个性别字段是不用加索引的。

如果你想要在 100 万行数据中查找其中的 50 万行(比如性别为男的数据),一旦创建了索引,你需要先访问 50 万次索引,然后再访问 50 万次数据表,这样加起来的开销比不使用索引可能还要大。

但是我们不能以偏概全,如果一个乒乓球队,女性只有1人,男性人数将近占到99%。这样建立索引还是有效的。不仅要看字段中的值得重复度,(0代表女,1代表男 )还要根据数值的分布情况(女性只占很小的一部分,男性占很大一部分)是需要建立索引的。

2. 索引的种类

2.1 按照字段个数划分

单一索引 :索引列为一列。
联合索引 :多个列组合在一起创建的索引。

联合索引存在最左匹配原则,创建联合索引时,列的先后顺序对查询效率也要一定的影响,例如(x,y,z)和(y,z,x)索引顺序的不同对查询效率也有一定的影响。所谓的最左匹配原则,顾名思义最先满足前面列,例如联合索引的顺序为x,y,z。如果查询条件为x=1 AND y=2 AND z=3 或者 x=1 AND y=2 或者x=1,该联合索引就可以使用,如果一开始就匹配y或者z,则联合索引失效。

2.2 按照逻辑划分

普通索引:最基础的索引,无任何约束,一张表中可以有多个。
唯一索引:在普通索引基础上增加了唯一性约束(UNIQUE),一张表中可以有多个。
主键索引:在唯一索引(UNIQUE)基础上增加不为空的约束(NOT NULL),一张表中只有一个。
全文索引:通常用作搜索引擎用,基本不用,作搜索引擎通常使用ES。

2.3 按照物理划分划分

聚集索引:数据表中的每行数据,按照索引排序方式进行数据的顺序存储,数据在物理上的存储顺序是一致的。如果找某一汉字,可以通过汉字的拼音直接找到。聚集索引数据直接存放在B+Tree的叶子节点中。索引和数据一一对应,一个表中只可以有一个聚集索引。因为数据时按顺序存放的,可见对数据进行插入删除更新效率比非聚集索引低。

非聚集索引:数据在物理上的存储是随机的,例如以下两个汉字,“江河” 在字典中的存储顺序是不一致的,也就是物理上的不一致,是随机存放的。所谓的非聚集索引就好比通过汉字的偏旁部首来找汉字,大致分为两步,首先第一步先找到索引,也就是找到汉字的偏旁部首 “ ”,其次在根据这个索引找到汉字。非聚集索引只是维护自己的索引表即可,所以非聚集索引叶子节点中只存放该汉字的具体位置。
“这个汉字,我们既可以通过偏旁部首 " " 找到它 ,也可以通过偏旁部首 “十”,找到该汉字,可见一张表中可以有多个非聚集索引。
由于数据随机存放,所以对表进行插入删除更新等操作效率高于聚集索引,查询速率低于聚集索引。

在这里插入图片描述

3.总结

索引可以提高对表数据的查询效率,然而数据表数据量小于1000 行,字段的数值重复度高于10%,也不适合用索引。当然索引也存在一些不足,比如占用存储空间、降低数据库写操作的性能等,如果有多个索引还会增加索引选择的时间。当我们使用索引时,需要平衡索引的利(提升查询效率)和弊(维护索引所需的代价)。其次我们学习了索引的常用模型,讲到了,哈希链表,有序数组,以及搜索树等存储模型,不同的模型有各自的优缺点。平衡利弊,还是那句话,没有最好的,只要最适合的。

发布了250 篇原创文章 · 获赞 448 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/fjxcsdn/article/details/105327671
今日推荐