前两篇文章我总结了一些SQL数据库索引的问题,这篇主要来分析下索引的优缼点,以及如何正确使用索引。
  
    索引的优点:这个显而易见,正确的索引会大大提高数据查询,对结果进行排序、分组的操作效率。
    索引的缺点:优点显而易见,同样缺点也是显而易见:
    1:创建索引需要额外的磁盘空间,索引最大一般为表大小的1.2倍左右。
    2:在表数据修改时,例如增加,删除,更新,都需要维护索引表,这是需要系统开销的。
    3:不合理的索引设计非但不能利于系统,反而会使系统性能下降。例如我们在一个创建有非聚集索引的列上做范围查询,此列的索引不会起到任何的优化效果,反而由于数据的修改而需要维护索引表,从而影响了对数据修改的性能。

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

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

2:不存在聚集索引。
          (1):在学分上没有索引,其它字段有索引,这种情况就会出现表扫描。
          (2):在学分上有索引,是否会按照学分上的索引进行查找呢?由于上面的表数据量也不少,一般会认为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:避免对不常用的列,逻辑性列,大字段列创建索引。

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

作者:姜敏
出处:http://www.cnblogs.com/aspnet2008/

 

转载于:https://www.cnblogs.com/ASPNET2008/archive/2010/12/19/1910218.html

软件开发人员真的了解SQL索引吗(索引使用原则)相关推荐

  1. 好程序员Java分享SQL语言之索引

    好程序员Java分享SQL语言之索引,前言:本章我们将学习MySQL中的索引,本文将从索引的作用.索引的分类.创建索引的语法.索引的使用策略以及索引的实现原理等方面带大家了解索引. 索引的作用 索引的 ...

  2. java开发对学位证_软件开发人员真的需要学位吗?

    java开发对学位证 当我刚开始从事软件开发人员的职业时,我没有学位. 我从大学一年级的暑假开始从事第一份真正的工作. 到了夏天,到了重新入学的时候,我发现我从那个暑假工作中获得的薪水与我大学毕业时的 ...

  3. SQL Server创建索引

    什么是索引 拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K .为了加快查找的速度,汉语字(词)典一般都有按拼音. ...

  4. sql加上唯一索引后批量插入_阿里大佬总结的52条SQL语句性能优化策略,建议收藏...

    你知道的越多,不知道的就越多,业余的像一棵小草! 你来,我们一起精进!你不来,我和你的竞争对手一起精进! 编辑:业余草 cnblogs.com/SimpleWu/p/9929043.html 推荐:h ...

  5. SQL Server 解读【已分区索引的特殊指导原则】(3) - 非聚集索引分区

    一.前言 在MSDN上看到一篇关于SQL Server 表分区的文档:已分区索引的特殊指导原则,如果你对表分区没有实战经验的话是比较难理解文档里面描述的意思.这里我就里面的一些概念进行讲解,方便大家的 ...

  6. SQL Server创建索引(转)

    什么是索引 拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K .为了加快查找的速度,汉语字(词)典一般都有按拼音. ...

  7. 阿里P8架构师谈:MySQL数据库的索引原理、与慢SQL优化的5大原则

    MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓"好马配好鞍",如何能够更好的使用它,已经成为开发工程师的必修 ...

  8. 你真的会使用数据库的索引吗?

    摘要:使用索引也很简单,然而, 会使用索引是一回事, 而深入理解索引原理又能恰到好处使用索引又是另一回事. 本文分享自华为云社区<索引到底能提升多少查询效率?何时该使用索引?一文快速搞懂数据库索 ...

  9. MySQL高级篇(SQL优化、索引优化、锁机制、主从复制)

    目录 0 存储引擎介绍 1 SQL性能分析 2 常见通用的JOIN查询 SQL执行加载顺序 七种JOIN写法 3 索引介绍 3.1 索引是什么 3.2 索引优劣势 3.3 索引分类和建索引命令语句 3 ...

最新文章

  1. 某34岁程序员哀叹:北京有一套房和160万现金,但500万的股票缩水到70万,上周刚失业,今天跟女友分手,心态崩了!...
  2. matlab调用kmeans_K_Means算法的MATLAB实现
  3. (24)2-9-9-12分页(上)
  4. Oracle中Merge into的用法实例讲解
  5. 论文|Item2vec中值得品味的8个经典tricks
  6. ECMAscript6入门(1)
  7. 第四章 类中数据的共享和保护
  8. Centos7 下载安装Redis
  9. 给群联PS3111/inic6081量产工具添加闪存颗粒支持
  10. 破解大众点评字体反爬
  11. gdb 调试 redis-cli 命令发送接收流程
  12. 【Python】Talk Python To Me Podcast播客
  13. oracle学习笔记(四)-- 数学函数
  14. 微信小程序生成带logo二维码
  15. 【升级版】python全自动定时,循环发消息(微信、QQ),零基础应用,
  16. 2018西安工业大学第二届萌新线上赛MISC WP
  17. ionic-移动端web的性能优化开源组件
  18. 一些你可能不知道的Flash XSS技巧
  19. SWFObject是什么
  20. 机房迁移测试时需要注意事项

热门文章

  1. golang避免SQL注入
  2. 底层经典书籍-编译原理
  3. golang中的TestMain
  4. jvm:运行时数据区
  5. 按钮滑动隐藏,停止滑动显示的动画
  6. VisualStudioCode插件下载
  7. Pandas基础复习-DataFrame
  8. vs插件ZunKoIDE
  9. ASP.NET MVC5 高级编程 第3章 视图
  10. 以软件开发生命周期来说明不同的测试的使用情况