SQL Server查询性能优化之创建合理的索引(下)

发表于:2012-7-06 09:44

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:懒惰的肥兔    来源:51Testing软件测试网采编

  续上一篇SQLServer查询性能优化之创建合理的索引(上)

  数据库索引分为聚集索引和非聚集索引,聚集索引就是物理索引,也就是数据的物理的存储顺序,聚集索引的叶子节点就是数据行本身;非聚集索引是逻辑索引,也可以简单的认为是对聚集索引建立的索引,一般来说聚集索引的键就是非聚集索引的叶子节点(在不使用include时)。

  关于索引的选择

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

  聚集索引

  聚集索引作为最重要的索引往往被我们所忽略,而其最大的优势就是大范围数据查询有着较高的效率,因此聚集索引列的选择往往对数据库性能有着灰常大的影响。为了尽量发挥聚集索引在大范围数据查找上的优势,推荐按以下顺序选择聚集索引列。

  聚集索引字段选择优先级:时间字段>>会进行大范围查询的列>>具有唯一值的有实际意义的字段>>自增列ID

  1、时间字段:若表里面有时间列,并且时间是按照数据插入顺序增长时(时间无需唯一即可有重复值,哪怕是大范围重复),建议采用时间列作为聚集索引的第一选择。理由:聚集索引有一个巨大的优势就是进行大范围数据查找,而且这个优势会随着数据量的增加而越来越明显,一般来说我们需要进行大数据量范围查询时都会用时间列围作为筛选条件,由于聚集索引不存在书签查找而且可以进行连续扫描,因此查询速度会非常快。时间列数据最好是顺序插入的这样可以尽量减少磁盘碎片,是数据存储相对集中,便于连续数据读取。

  2、会进行大范围查询的列:若表里面没有时间字段或者时间字段不适合做聚集索引,可以选择那些在建表时就明确知道会经常进行大范围数据筛选的列,而且最好是选择性较低的列(即有较多重复值的列,性别这种列不算啦),如有必要可以使用组合索引。理由:聚集索引在数据查询的优势主要在于范围数据查找,把聚集索引弄成唯一的把这个大好优势给白白浪费了。

  3、具有唯一值的有实际意义的字段:若找不到适合条件1、2的列,那还是乖乖的把聚集索引列建立在唯一列上吧,最好找那种有实际意义的具有唯一性的列,比如订单表可以用订单号作聚集索引,订单明细表使用订单号和产品编号做联合聚集索引。理由:找不到合适的时间字段和较低选择性字段的话,把主键建成聚集索引是我们大多情况下的选择。

  这里建议把唯一性的聚集索引顺便建成主键,和编码时方法、变量命名一样,推荐列名自解释,即看到列名就知道它就是主键,省得你再去猜,比如订单表你来个自增ID列做主键,再建一个OrderCode列做订单号,用这个表时你得怀疑这个OrderCode是不是唯一滴呢,有木有建立唯一约束呢,同理在订单明细表来个自增列ID也会产生如此疑问,产生疑问还是小事,若是你忘记了在应该唯一的列上建立约束,没准哪天程序控制不好给你个巨大的惊喜。

  4、自增列ID:前面3中条件都找不到合适的列了还是使用我们的神器自增列ID吧,自增列ID也是我们使用最多的主键(顺便也就成聚集索引了),而且能较好满足我们大多数需求。自增ID列堪称无所不能,int类型只占用4个字节完全满足窄索引要求,绝对的顺序存储可以有效降低索引碎片,完全符合我们的见表习惯,有用没用来个自增ID列做主键总是没错滴。

  这里考虑聚集索引的键列主要为查询考虑,有些观点认为应该总是把聚集索引建立唯一列上,这里不敢苟同,诚然有些特殊情况下确实需要这么做,但大说情况下还是建立在选择性较低的列、时间列上比较好,这样才能发挥聚集索引在范围数据查找方面的巨大优势。关于聚集索引在列上重复数据SQL Server需要额外的建立唯一标示用以定位造成查询时的额外开销非常小,小到与其带来范围查找的优势而言完全可以忽略。

  当然了在选择列时要尽量使用窄索引,也只是尽量而已,主要还是看付出的代价还获得的收益,若有足够的收益啥玩意都可以滴。记住我们滴目标是利用聚集索引提高大范围查询效率。

  非聚集索引

  与聚集索引不同,非聚集索引可以建立多个,这也给我们带来了很大的灵活,毕竟聚集索引就那么一个不可能靠它满足所有需求,更多的我们得依赖非聚集索引。记住非聚集索引不是大白菜,你想键多少就建多少,建立索引是有代价的,任何涉及到索引列的数据修改都会导致索引的修改,索引越多数据的曾、删、改的额外代价也就越大。对于非聚集索引来说,我们的目标是用尽可能少的索引覆盖尽可能多的查询。

  非聚集索引的列选择顺序(组合索引):经常被使用为查询条件列>>具有较高选择性的列(选择性越高越好,唯一最好)>>经常排序的列

  1、经常被使用为查询条件列:我们的查询千变万化,建立索引时要首先考虑有哪些列被经常性的用于各种查询,把使用频率较高的列作为组合索引的第一列(先导列),若一个查询中没有用到组合索引中的先导列,多数情况下这个索引就不会被使用,因此为了尽可能多的复用组合索引把使用较多的查询列作为组合索引的第一列吧。(关于这点对于聚集索引的组合索引同样适用)

  2、具有较高选择性的列:这点很简单尽量使用高选择性列作为先导列,如果可以通过第一个条件过滤(随便什么判定逻辑=、>、<、like),只要能大幅减少数据范围,就把它作为先导列。

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号