文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>软件开发人员真的了解SQL索引吗(索引使用原则)

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

时间:2010-12-19  来源:姜敏

     实际例子:还是拿前两篇文章的学生表来讲吧,要查询成绩在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/ 

 

 

   

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载