设为首页 收藏本站
查看: 626|回复: 0

[经验分享] Sql Server查询性能优化之创建合理的索引(下篇)

[复制链接]

尚未签到

发表于 2015-6-27 14:53:36 | 显示全部楼层 |阅读模式
  最近貌似比较忙,突发现好久木有写博客了。。。
  续上一篇 Sql Server查询性能优化之创建合理的索引(上篇)
  数据库索引分为聚集索引和非聚集索引,聚集索引就是物理索引,也就是数据的物理的存储顺序,聚集索引的叶子节点就是数据行本身;非聚集索引是逻辑索引,也可以简单的认为是对聚集索引建立的索引,一般来说聚集索引的键就是非聚集索引的叶子节点(在不使用include时)。

关于索引的选择
  对于索引类型来说没什么好选的,一般来说聚集索引是必须的(有特殊需要的另说),非聚集索引看实际需要灵活建立。因此对于索引来说主要是决定在那些列上建立索引,尤其是对于聚集索引这点非常重要。

聚集索引
  聚集索引作为最重要的索引往往被我们所忽略,而其最大的优势就是大范围数据查询有着较高的效率,因此聚集索引列的选择往往对数据库性能有着灰常大的影响。为了尽量发挥聚集索引在大范围数据查找上的优势,推荐按以下顺序选择聚集索引列。
  聚集索引字段选择优先级:时间字段>>会进行大范围查询的列>>具有唯一值的有实际意义的字段>>自增列ID
  1.时间字段:若表里面有时间列,并且时间是按照数据插入顺序增长时(时间无需唯一即可有重复值,哪怕是大范围重复),建议采用时间列作为聚集索引的第一选择。理由:聚集索引有一个巨大的优势就是进行大范围数据查找,而且这个优势会随着数据量的增加而越来越明显,一般来说我们需要进行大数据量范围查询时都会用时间列围作为筛选条件,由于聚集索引不存在书签查找而且可以进行连续扫描,因此查询速度会非常快。时间列数据最好是顺序插入的这样可以尽量减少磁盘碎片,是数据存储相对集中,便于连续数据读取。
  2.会进行大范围查询的列:若表里面没有时间字段或者时间字段不适合做聚集索引,可以选择那些在建表时就明确知道会经常进行大范围数据筛选的列,而且最好是选择性较低的列(即有较多重复值的列,性别这种列不算啦),如有必要可以使用组合索引。理由:聚集索引在数据查询的优势主要在于范围数据查找,把聚集索引弄成唯一的把这个大好优势给白白浪费了。
  3.具有唯一值的有实际意义的字段:若找不到适合条件1、2的列,那还是乖乖的把聚集索引列建立在唯一列上吧,最好找那种有实际意义的具有唯一性的列,比如订单表可以用订单号作聚集索引,订单明细表使用订单号和产品编号做联合聚集索引。理由:找不到合适的时间字段和较低选择性字段的话,把主键建成聚集索引是我们大多情况下的选择。
  这里建议把唯一性的聚集索引顺便建成主键,和编码时方法、变量命名一样,推荐列名自解释,即看到列名就知道它就是主键,省得你再去猜,比如订单表你来个自增ID列做主键,再建一个OrderCode列做订单号,用这个表时你得怀疑这个OrderCode是不是唯一滴呢,有木有建立唯一约束呢,同理在订单明细表来个自增列ID也会产生如此疑问,产生疑问还是小事,若是你忘记了在应该唯一的列上建立约束,没准哪天程序控制不好给你个巨大的惊喜。
  4.自增列ID:前面3中条件都找不到合适的列了还是使用我们的神器自增列ID吧,自增列ID也是我们使用最多的主键(顺便也就成聚集索引了),而且能较好满足我们大多数需求。自增ID列堪称无所不能,int类型只占用4个字节完全满足窄索引要求,绝对的顺序存储可以有效降低索引碎片,完全符合我们的见表习惯,有用没用来个自增ID列做主键总是没错滴。
  这里考虑聚集索引的键列主要为查询考虑,有些观点认为应该总是把聚集索引建立唯一列上,这里不敢苟同,诚然有些特殊情况下确实需要这么做,但大说情况下还是建立在选择性较低的列、时间列上比较好,这样才能发挥聚集索引在范围数据查找方面的巨大优势。关于聚集索引在列上重复数据SQL Server需要额外的建立唯一标示用以定位造成查询时的额外开销非常小,小到与其带来范围查找的优势而言完全可以忽略。
  当然了在选择列时要尽量使用窄索引,也只是尽量而已,主要还是看付出的代价还获得的收益,若有足够的收益啥玩意都可以滴。记住我们滴目标是利用聚集索引提高大范围查询效率。

非聚集索引
  与聚集索引不同,非聚集索引可以建立多个,这也给我们带来了很大的灵活,毕竟聚集索引就那么一个不可能靠它满足所有需求,更多的我们得依赖非聚集索引。记住非聚集索引不是大白菜,你想键多少就建多少,建立索引是有代价的,任何涉及到索引列的数据修改都会导致索引的修改,索引越多数据的曾、删、改的额外代价也就越大。对于非聚集索引来说,我们的目标是用尽可能少的索引覆盖尽可能多的查询。
  非聚集索引的列选择顺序(组合索引):经常被使用为查询条件列>>具有较高选择性的列(选择性越高越好,唯一最好)>>经常排序的列
  1.经常被使用为查询条件列:我们的查询千变万化,建立索引时要首先考虑有哪些列被经常性的用于各种查询,把使用频率较高的列作为组合索引的第一列(先导列),若一个查询中没有用到组合索引中的先导列,多数情况下这个索引就不会被使用,因此为了尽可能多的复用组合索引把使用较多的查询列作为组合索引的第一列吧。(关于这点对于聚集索引的组合索引同样适用)
  2.具有较高选择性的列:这点很简单尽量使用高选择性列作为先导列,如果可以通过第一个条件过滤(随便什么判定逻辑=、>、

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-80964-1-1.html 上篇帖子: SQL Server的FileStream和FileTable 下篇帖子: SQL Server 2012提供的OFFSET/FETCH NEXT与Row_Number()对比测试
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表