SQL索引优缺点

SQL索引优缺点前两篇文章我总结了一些SQL数据库索引的问题,这篇主要来分析下索引的优缼点,以及如何正确使用索引。索引的优点:这个显而易见,正确的索引会大大提高数据查询,对结果进行排序、分组的操作效率。索引的缺点:优点显而易见,同样缺点也是显而易见:1:创建索引需要额外的磁盘空间,索引最大一般为表大小的1.2倍左右。2:在表数据修改时,例如增加,删除,更新,都需要维护索引表,这是需要系统开销的

大家好,又见面了,我是你们的朋友全栈君。

前两篇文章我总结了一些SQL数据库索引的问题,这篇主要来分析下索引的优缼点,以及如何正确使用索引。

索引的优点:这个显而易见,正确的索引会大大提高数据查询,对结果进行排序、分组的操作效率。
索引的缺点:优点显而易见,同样缺点也是显而易见:
1:创建索引需要额外的磁盘空间,索引最大一般为表大小的1.2倍左右。

2:在表数据修改时,例如增加,删除,更新,都需要维护索引表,这是需要系统开销的。
3:不合理的索引设计非但不能利于系统,反而会使系统性能下降。例如我们在一个创建有非聚集索引的列上做范围查询,此列的索引不会起到任何的优化效果,反而由于数据的修改而需要维护索引表,从而影响了对数据修改的性能。

实际例子:还是拿前两篇文章的学生表来讲吧,要查询成绩在50分以上的学生信息select * from student where score>50。学生表包含了100000行记录,而且学分是随机生成的,这样从数据量以及数据分布上都有一定的保障。

第一种情况:学生表有索引。
1:存在聚集索引,但聚集索引不在学分上,这里只分析学分不是聚集索引的情况。
(1):学分上没有索引。此时SQL会通过聚集索引来查找数据,这点估计大家都会知道。
(2):学分上有索引。这种情况,SQL会使用上学分上的索引吗?这个问题估计不是每个人都能回答正确的。既然学分上有索引,而where中又有此列,理应使用了索引,但实际情况并没有使用索引。因为出现了范围查找,如果一个索引一个索引的比较,在性能上比起直接按聚集索引查找全部数据后再过滤来的差。那学分上的索引什么时候 SQL会优先考虑呢?当score指定为一个具体值时,就能使用学分索引查找了。从下图的SQL执行计划可以得知。

SQL索引优缺点

2:不存在聚集索引。
(1):在学分上没有索引,其它字段有索引,这种情况就会出现表扫描。
(2):在学分上有索引,是否会按照学分上的索引进行查找呢?由于上面的表数据量也不少,一般会认为SQL不会采用表扫描,因为会查找全部记录,但实际情况表明SQL对于范围查询也行采用表扫描而不是按学生索引查询。我们也可以强制SQL按学分查询,于是有下面的SQL执行计划比较,我们可以清楚的看出,强制使用学分做为索引查询比表搜索的性能要差很多。

SQL索引优缺点

第二种情况:学生表没有索引。这个情况没有分析的价值。

什么字段不适合创建索引?
1:不经常使用的列,这种索引带来缺点远大于带来的优点。
2:逻辑性的字段,例如性别字段等等,匹配的记录太多,和表扫描比起来不相上下。
3:字段内容特别大的字段,例如text等,这会大大增大索引所占用的空间以及索引更新时的速度。

我们说SQL在维护索引时要消耗系统资源,那么SQL维护索引时究竟消耗了什么资源?会产生哪些问题?究竟怎样才能优化字段的索引?

第一:当数据页达到了8K(数据页最大为8K) 容量,如此时发生插入或更新数据的操作,将导致页的分裂。
1、聚集索引的情况下:聚集索引将被插入和更新的行指向特定的页,该页由聚集索引关键字决定;
2、只有堆的情况下:有空间就可以插入新的行,对行数据的更新需要更多的空间,如果大于了当前页的可用空间,行就被移到新的页中,且在原位置留下一个转发指针,指向被移动的新行,如果具有转发指针的行又被移动了,那么原来的指针将重新指向新的位置;
3、堆中有非聚集索引,尽管插入和更新操作,不会发生页分裂,但非聚集索引上仍然产生页分裂。
总结:无论有无索引,很多数据将保留在老页面,其它将放入新页面,并且新页面可能被分配到任何可用的页,频繁页分裂,表会产生大量数据碎片,直接造成I/O 效率下降。

引出问题:为什么数据库对于varchar最大值设置为8000,而不是10000呢?
答:是由于数据页大小最大为8K。

第二:针对上述索引可能造成的页分页的解决方案,填充因子。
创建索引时,可以为索引指定一个填充因子,在索引的每个叶级页面上保留一定百分比的空间,将来数据可以进行扩充和减少页分裂。值从0到100的百分比数值,100 时表示将数据页填满。不对数据进行更改时(例如只读表中)才用此设置,实用价值不大。值越小则数据页上的空闲空间越大,可以减少在索引增长过程中进行页分裂,但需要占用更多的硬盘空间。填充因子也不能设置过小,过小会影响SQL的读取性能,因为填充因子造成数据页的增多。一般我们公司设置的填充因子是80。

索引是否是一尘不变的?
随着业务的变化,数据的变化,会发生有些索引的用处可能发生变化,例如:
1:原来主要靠用户名搜索记录,现在业务更改为按用户所在城市搜索等等,此时我们需要即时变更表索引以适应新业务的变化,即数据和使用模式发生了大幅度变化。
2:系统上线前不合理的索引,随着数据的增加,缺点越来越明显,此时需要调整索引。
3:随着数据的增加,产生了越来越多的页分裂,导致索引性能越来越低。

上面的几种情况,我们就需要选择重建索引来彻底解决问题。

总结索引使用原则:
1:不要索引数据量不大的表,对于小表来讲,表扫描的成本并不高。
2:不要设置过多的索引,在没有聚集索引的表中,最大可以设置249个非聚集索引,过多的索引首先会带来更大的磁盘空间,而且在数据发生修改时,对索引的维护是特别消耗性能的。
3:合理应用复合索引,有某些情况下可以考虑创建包含所有输出列的覆盖索引。
4:对经常使用范围查询的字段,可能考虑聚集索引。
5:避免对不常用的列,逻辑性列,大字段列创建索引。

有说的不对的地方,欢迎大家指正。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/141194.html原文链接:https://javaforall.net

(0)
上一篇 2022年5月26日 下午1:40
下一篇 2022年5月26日 下午1:40


相关推荐

  • shmget物理内存_shmget共享内存

    shmget物理内存_shmget共享内存Linux 为共享内存提供了四种操作 1 共享内存对象的创建或获得 与其它两种 IPC 机制一样 进程在使用共享内存区域以前 必须通过系统调用 sys ipc call 值为 SHMGET 创建一个键值为 key 的共享内存对象 或获得已经存在的键值为 key 的某共享内存对象的引用标识符 以后对共享内存对象的访问都通过该引用标识符进行 对共享内存对象的创建或获得由函数 sys shmget 完成 其定义如下 int

    2026年3月19日
    2
  • python中延时函数_python延时函数

    python中延时函数_python延时函数广告关闭腾讯云11.11云上盛惠,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元!可以使用python的time模块来实现类似于c中的sleep函数作用代码如下:importtimedefsleep(mytime=‘’):time.sleep(mytime)printcallsleepsleep(5)#sleep5sprint‘sleepen…

    2022年6月17日
    63
  • django textfield_微擎应用模块源码

    django textfield_微擎应用模块源码前言上一篇分析了请求模块的源码,如下:definitialize_request(self,request,*args,**kwargs):"""Retu

    2022年7月29日
    8
  • 最小可用maven+springboot 项目(无法使用外网,但是有maven私库情况)

    最小可用maven+springboot 项目(无法使用外网,但是有maven私库情况)用的是ideal,jdk1.8具体操作,参考下面链接。致谢:感谢下面作者的博客https://blog.csdn.net/weixin_43293627/article/details/82877418https://blog.csdn.net/u011948899/article/details/78159027https://www.phpsong.com/3463.ht…

    2022年7月18日
    11
  • 科大讯飞发布星火认知大模型

    科大讯飞发布星火认知大模型

    2026年3月14日
    3
  • Centos7 postfix dovecot安装配置

    Centos7 postfix dovecot安装配置基本流程及软件版本最近在为公司搭建私有服务器环境 调研了一些开源或付费软件 最后选择自己配置软件环境 以下为配置过程及测试 Postfix 一种邮件传输代理软件 通常用来发送邮件 Dovcot 邮件检索代理软件 通常用来接收邮件 发送流程 客户端 MailClient 发出邮件 amp amp amp gt Postfix 接收 通过 Dovecot 进行认证 查询数据库是否存在用户 amp amp amp gt Dovecot 把

    2026年3月17日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号