在本文中我们将推荐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. html和js

    1.<input type="button" value="Hello world!"> 2.<button type="butto ...

  2. 网易云课堂_程序设计入门-C语言_第三周:循环_1奇偶个数

    1 奇偶个数(5分) 题目内容: 你的程序要读入一系列正整数数据,输入-1表示输入结束,-1本身不是输入的数据.程序输出读到的数据中的奇数和偶数的个数. 输入格式: 一系列正整数,整数的范围是(0,1 ...

  3. VS2010在C盘下生成的.iTrace文件解决办法 ,c盘偷偷的减少,心很烦啊,找了半天才知道是这个问题

    用Visual Studio 2010后发现我的c盘变得越来越小了,刚开始通过优化工具清理c盘,但是无论怎么做都不能将c的内存有效提升,之后一个一个目录的查找之后才知道有个文件夹C:\ProgramD ...

  4. c++中冒号(:)和双冒号(::)的用法

    1.冒号(:)用法 (1)表示机构内位域的定义(即该变量占几个bit空间) typedef struct _XXX{ unsigned ; unsigned char c; } ; XXX (2)构造 ...

  5. Oracle错误ORA-03113: end-of-file on communication channel处理办法

    oracle不能启动了,报错ORA-03113: end-of-file on communication channel (通信通道的文件结尾) 解决办法: SQL> startup ORAC ...

  6. Lua的元方法__newindex元方法

    上一篇介绍了__index元方法,总结来说:__index元方法是用于处理访问table中不存在的字段时的情况. 而今天,介绍的__newindex元方法,总结来说,就是:用于处理给table中不存在 ...

  7. Android DatePicker和TimePicker

    监测日期改变的监听器:      OnDateChangedListener和OnTimeChangedListener()           当用户改变Datepicker里的年.月.日时,将触发 ...

  8. 分析JavaScript代码应该放在HTML代码哪个位置比较好

    本文总结了多种放置JS代码的方法,需要的朋友可以参考下 在哪里放置 JavaScript 代码? 通常情况下,JavaScript 代码是和 HTML 代码一起使用的,可以将 JavaScript 代 ...

  9. linux下/proc/sysrq-trigger文件的功能

    /proc/sysrq-trigger该文件能做些什么事情呢? # 立即重新启动计算机 (Reboots the kernel without first unmounting file system ...

  10. Cocos2d-x 安装教程for mac(Xcode)

    cocos2d v3.x 版本出来后,从配置安装到创建项目都是命令行,下面简单说一下. 1. 下载地址    http://cn.cocos2d-x.org/download/ (虽然没有标明 for ...