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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • golang json 转map

    golang json 转map//convertjsontomappackagemainimport(“fmt””encoding/json”)funcmain(){b:=[]byte(`{“IP”:”192.168.11.22″,”name”:”SKY”}`)m:=make(map[string]string)err:=json.Unmarsha

    2022年6月16日
    231
  • 人工势场法(APF) —— Path Planning「建议收藏」

    人工势场法(APF) —— Path Planning「建议收藏」版权声明:本文为博主原创博文,未经允许不得转载,若要转载,请说明出处并给出博文链接人工势场法(ArtificialPotentialField,APF)是一种将机器人的外形视为势场中的一个点,这个势场结合了对目标的吸引力和对障碍物的排斥力。得到的轨迹作为路径输出。该方法具有计算量小、容易理解等优点。然而,它们可能陷入势场的局部极小值而无法找到路径,或者无法找到最优路径。人工势场可以被视为与静电势场类似的连续方程(将机器人视为点电荷),或者通过场的运动可以使用一组语言规则进行离散…

    2022年6月17日
    40
  • 搭建smtp邮件服务器_smtp服务器怎么填

    搭建smtp邮件服务器_smtp服务器怎么填4.“传递”选项卡在“默认SMTP虚拟服务器属性”对话框中点击“传递”选项卡,如图所示。该选项卡用来设定邮件一次发送不成功时,SMTP服务器如何处理这些邮件。在大多数情况下,每个虚拟服务器都尽量在消息一抵达消息队列后就进行发送;可是,如果下一个中继段的服务器发生了某个临时性的问题,或者网络中发生了某种通信故障,那么虚拟服务器就会采取适当的措施,例如对消息进行排队,准备再次重试,或者变更消息路由。如…

    2022年10月3日
    0
  • gradle项目导包出现Could not GET connect refuse 之类的

    gradle项目导包出现Could not GET connect refuse 之类的

    2020年11月9日
    219
  • 正则表达式Python_js正则表达式实例

    正则表达式Python_js正则表达式实例正则表达式详解正则表达式英文名称叫RegularExpression简称RegEx,是用来匹配字符的一种工具,它常被用在网页爬虫,文稿整理,数据筛选等方面,最常用的就是用在网页爬虫,数据抓取。一、正则表达式的各种符号解释(来自维基百科)~~~是不是感觉太多了,因此我将常用的整理出来了二、进行逐个详解1.首先导入模块importre2.匹配多种可能使用[]…

    2022年10月3日
    0
  • Windows下 文件夹加密

    Windows下 文件夹加密此加密方法會使这个特殊的文件夹用正常情况不可打開也不可删除,可以起到保护重要资料的作用。  在Windows中“\”符号是路径的分隔符,比如“C:\Windows\System.exe”的意思是C分区的Windows文件夹中的System.exe文件。如果文件名中有“\”符号会怎么样呢?假如“sexinsex\”是一个文件夹的名字,这个文件夹位于“F:\”,它的路径就是“F:\sexinse…

    2022年7月13日
    22

发表回复

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

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