在本文中我们将推荐14条贯穿本系列的规则,这些规则帮助你为数据库创建最好的索引结构。

格式来自于《Framework Design Guidelines》。每条推荐用四个词来总结:Do做,Consider考虑,Void避免,Do Not不要做。

  • 做。总是要遵守的规则。
  • 考虑。通常来说应该遵守,但是如果你完全理解了规则背后的原因,并且有你不遵守的原因。
  • 避免。和考虑相反,通常建议不这么做,但是如果你完全理解了为什么不应该这么做,你有这么做的原因,你可以这么做。
  • 不要做。比避免语气要强,表面有些事永远不要做。

指导原则

Do know your Application/Users

索引的主要目的是提高查询和操作数据的性能,除非你知道这些操作是什么,否则你没有希望改进他们。

最好是在应用的开始就考虑,在设计和开发中加入。如果你继承了一个已经存在的数据库和应用,从两方面理解你继承的是什么:内部和外部。

外部包括从用户角度,和他们聊天,观察他们使用应用,阅读用户文档和手册,查看当前的表格和报表。

内部包括检查应用本身,应用的定义和应用的执行。使用工具,Activity Monitor,Profiler,sys.dm_db_index usage_stats动态视图,以及sys.dm_db_missing_index_XXX系列的动态视图观察常用查询,慢查询,常用索引,未使用的索引,应该存在但却没有建立的索引。

检查常用查询和慢查询的源头,例如,报表服务的模板。TSQL作业的步骤,SSIS应用中的TSQL任务,存储过程,都应该被优化。

在了解了这些信息之后,对于那些索引是好的,那些索引是不好的,你就可以做出更好的决定。

Do Not Over Index

索引太多和太少都是不好的。对表来说没有“最佳索引个数”这种说法。每张表的情况都不同。但是如果你要在主键,候选键,合适的外键,潜在的查询列上建立索引,请在建立之前做一些分析。

Do Understand that:Same Database + Different Situation = Different Indexing

不管是白天处理,还是非高峰期处理;不管是联机处理,还是对数据库拷贝的报表处理;不同的情况,建立的索引是不同的。

Do Have a Primary Key on Every Table

尽管主键不是SQL Server必须的,但是没有主键的表在事务的时候是非常危险的,因为不能保证行是唯一的。如果允许重复行,就会发生,你不知道是同一个实体重复插入了两次,还是没有足够的信息来区分这两个实体。

尽管SQL Server没有要求,主键是关系理论的基础,所有关系系统的基本构成。没有主键的约束,或者是唯一索引,可能会导致意外的结果,或者不好的性能。

另外,很多客户端开发工具和组件都需要你的表有主键。主键约束的名称就是索引的名称。

Consider Having a Clustered Index on Every Table

第三级,聚集索引介绍了聚集索引的好处。让表成为聚集索引表而不是堆表。主要的好处是一个简单的事实,用户在查看表数据的时候肯定会以一个默认的顺序,所以就以哪个顺序来维护表。

如果你按照本文的规则,每张表都有主键,每张表至少有一个索引,甚至更多。因此,一个聚集索引不会增加索引的数量,但是相比堆表,会给你的表带来一个很好的结构。

在决定聚集索引列的时候,要记住第六级,标签中的指导原则:一个聚集索引应该唯一,短小,不变的。

Consider Using a Foreign Key in the Search Key of the Clustered Index

考虑将外键作为聚集索引键中最左面的列,这样可以将子item的信息聚集在父的周围,这是一个典型的需求。你的信用卡的消费信息和信用卡关联,我的消费信息和我的卡关联。这个关系要比消费记录和商家,或者消费记录和处理消费记录的金融机构,要比这些关系强。卡号是包含在消费表的聚集索引键中的外键,而不是商家编号和银行编号。将卡号放在聚集索引的最左边,同一个持卡人的消费记录就会聚集在相同的页中。

Consider Having Included Columns in your Indexes

考虑在你的非聚集索引中添加包含列。

因为一般的非聚集索引都是从某种角度查看表,或者是建立的外键的基础上,但是除了非聚集索引的键列,还会需要一些其他列,但是这些列不作为查询条件,只是需要显示或者统计它们,这时候,这些列就可以添加为包含列,就不用再去访问数据行了,直接在非聚集索引中就可以完成请求。

Avoid Nonclustered, Unfilterd Indexes on Columns that have few Distinct Values

有句老话:“不要在性别列上建立索引”。表中的一页将会有一半的值为男,一半的值为女,不管是请求男还是女,扫描表都是最好的决定。因此,这样的一个索引永远不会被查询优化器使用。

Consider Create a Filtered Index for Columns that Have a Dominate Value

如果表中有一列,大部分行的值都相同,或者都是NULL,那么就在这列上创建一个过滤索引。那些查询小部分值的时候,就会使用索引;查询大部分值的时候就扫描表。

Consider Specifying Fill Factor Values that Anticipate Future Size Requirements

Consider Specifying Fill Factor Values that Reflect the Table's Steady-state Page Fragmentation Value

Do Create a Table's Clustered Index Before Creating its Nonclustered Indexes

这条规则的一个推论就是:删除聚集索引之前,先删除非聚集索引。否则会导致非聚集索引出现不必要的重建。表从堆表,转变成聚集索引表,总是会导致非聚集索引的重建,因为非聚集索引的书签的内容会从行号变成聚集索引的键。

Do Plan Your Index Defragmenting and Rebuilding Based Upon Usage

如果一个索引经常被扫描,索引的外部碎片是很重要的,对于全扫描或者扫描部分叶子层会产生重要的影响。如果是这种情况,在外部碎片达到10%的时候,考虑重新组织索引,当达到30%的时候,考虑重建索引。

但是,如果,索引只是通过一个键来查询,外部碎片对性能的影响很小,甚至没有影响。从根页到叶子层的一页所需要的IO,将会忽略外部碎片,将会是相同的。这时候,重新组织和重建索引对于性能没有提升。

Do Update Index Statistics On a Regular Basis

关键字是“规律的”,因为只有知道你的应用在做什么,你才能决定什么时候统计信息需要更新。在第十四级中有这部分的介绍。

结论

这些指导原则来自于很多在SQL Server上工作过多年的开发人员,根据这些指导原则,你可以在你的数据库上创建最好的索引。

SQL Server索引进阶:第十五级,索引的最佳实践的更多相关文章

  1. 为运行SQL Server的虚拟机切换装有DB Logs的最佳实践

    上一篇说到虚拟机启动不了, 原因是有一块VHDX的文件找不到了. 解决了这个问题之后, 又遇到了另一个问题, 那就是我的这台SQL Server的虚机启动之后, 我的几个重要database变成了su ...

  2. SQL Server 2005 中的分区表和索引

    SQL Server 2005 中的分区表和索引 SQL Server 2005          69(共 83)对本文的评价是有帮助 - 评价此主题   发布日期 : 3/24/2005 | 更新 ...

  3. SQL Server 2016:内存列存储索引

    作者 Jonathan Allen,译者 谢丽 SQL Server 2016的一项新特性是可以在“内存优化表(Memory Optimized Table)”上添加“列存储索引(Columnstor ...

  4. SQL Server ->> ColumnStore Index(列存储索引)

    Columnstored index是SQL Server 2012后加入的重大特性,数据不再以heap或者B Tree的形式存储(row level)存储在每一个数据库文件的页里面,而是以列为单位存 ...

  5. SQL Server 性能调优2 之索引(Index)的建立

    前言 索引是关系数据库中最重要的对象之中的一个,他能显著降低磁盘I/O及逻辑读取的消耗,并以此来提升 SELECT 语句的查找性能.但它是一把双刃剑.使用不当反而会影响性能:他须要额外的空间来存放这些 ...

  6. SQL Server的唯一键和唯一索引会将空值(NULL)也算作重复值

    我们先在SQL Server数据库中,建立一张Students表: CREATE TABLE [dbo].[Students]( ,) NOT NULL, ) NULL, ) NULL, [Age] ...

  7. SQL Server索引进阶:第五级,包含列

    原文地址: Stairway to SQL Server Indexes: Level 5, Included Columns 本文是SQL Server索引进阶系列(Stairway to SQL ...

  8. 【译】索引进阶(十二):SQL SERVER中的索引碎片【中篇】

    原文链接:传送门. 为了讨论碎片产生的原因,以及避免和移除索引碎片的技术,我们必须从本进阶系列后续将介绍的两个章节借用一些知识点:创建/更新索引的知识,以及向一个索引表插入数据行的相关知识. 当我们讲 ...

  9. 解读SQL Server 2014可更新列存储索引——存储机制

    概述 SQL Server 2014被号称是微软数据库的一个革命性版本,其性能的提升的幅度是有史以来之最. 可更新的列存储索引作为SQL Server 2014的一个关键功能之一,在提升数据库的查询性 ...

  10. SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析

    在SQL SERVER的查询语句中使用OR是否会导致不走索引查找(Index Seek)或索引失效(堆表走全表扫描 (Table Scan).聚集索引表走聚集索引扫描(Clustered Index ...

随机推荐

  1. RBF network

    1.radial basis function RBF表示某种距离,$\mu_m$为中心点,相当于将点$x$到中心点的某种距离作为特征转换 Output方法可以根据需求任意选取(比如使用SVM,log ...

  2. [11-3] Gradient Boosting regression

    main idea:用adaboost类似的方法,选出g,然后选出步长 Gredient Boosting for regression: h控制方向,eta控制步长,需要对h的大小进行限制 对(x, ...

  3. 原生网络请求以及AFN网络请求/异步下载

    这里对网络请求方式做一个总结. 原生方式同步GET请求: NSString *urlStr = @"http://apis.juhe.cn/mobile/get?phone=13429667 ...

  4. strcpy()、memcpy()、memmove()、memset()的内部实现

    一直想知道 strcpy().memcpy().memmove().memset()的内部实现 strcpy(), 字符串拷贝. char *strcpy(char *strDest, const c ...

  5. 初步STL集装箱List

    List 特点: 1.它实质上是一个双向链表 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ3hpYW9idXB0/font/5a6L5L2T/f ...

  6. for应用

    应用:迭代法,穷举法.一.迭代法:有一定规律. 每次循环都是从上次运算结果中获得数据,本次运算的结果都是要为下次运算做准备.例:1.100以内所有数的和.2.求阶乘3.求年龄.4.折纸.5.棋盘放粮食 ...

  7. 一些DevExpress控件概况!!!!主要DocumentManager.WindowsUIView.Tile

    WinForms Controls The links below provide comprehensive information on using DevExpress WinForms pro ...

  8. DevExpress中ChartControl柱状图(Bar)用法

    我的数据 代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 chartControl1.Series.Clear(); ...

  9. 【Sharepoint】CSS与Master Page的开发与部署

    一.CSS的开发与部署相对比较简单,先是要上传CSS文件到样式库中,然后在页面模板中将上传的自定义CSS样式文件设置为所有文件的默认css文件.下面详细的介绍CSS文件的开发与部署过程. 1.编写自定 ...

  10. iOS根据2个经纬度计算距离

    #pragma mark - calculate distance 根据2个经纬度计算距离 #define PI 3.14159265358979323 +(double) CalculationDi ...