使用索引的意义íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
  • 索引在数据库中的作用类似于目录在书籍中的作用,用来提高查找信息的速度。
  • 使用索引查找数据,无需对整表进行扫描,可以快速找到所需数据。
使用索引的代价íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
  • 索引需要占用数据表以外的物理存储空间。
  • 创建索引和维护索引要花费一定的时间。
  • 当对表进行更新操作时,索引需要被重建,这样降低了数据的维护速度。
创建索引的列íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
  • 主键
  • 外键或在表联接操作中经常用到的列
  • 在经常查询的字段上最好建立索引
不创建索引的列íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
  • 很少在查询中被引用
  • 包含较少的惟一值
  • 定义为 text、ntext 或者 image 数据类型的列
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
Heaps是staging data的很好选择,当它没有任何Index时íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
  • Excellent for high performance data loading (parallel bulk load and parallel index creation after load)
  • Excellent as a partition to a partitioned view or a partitioned table
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
聚集索引提高性能的方法,在前面几篇博客中分别提到过,下面只是一个简单的大纲,细节请参看前面几篇博客。íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
何时创建聚集索引?íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
Clustered Index会提高大多数table的性能,尤其是当它满足以下条件时:íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
  • 独特, 狭窄, 静止: 最重要的条件
  • 持续增长的,最好是只向上增加。例如:
    • Identity
    • Date, identity
    • GUID (only when using newsequentialid() function)
聚集索引唯一性(独特型的问题)íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
由于聚集索引的B+树结构的叶子节点必须指向具体数据。如果你要建立聚集索引的列不唯一,并且你指定的创建的聚集索引是非唯一的聚集索引,则会有以下情况:íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
如果未使用 UNIQUE 属性创建聚集索引,数据库引擎 将向表自动添加一个四字节 uniqueifier 列。必要时,数据库引擎 将向行自动添加一个 uniqueifier 值,使每个键唯一。此列和列值供内部使用,用户不能查看或访问。íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
参看这篇文章:íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
SQL Server 索引基础知识(4)----主键与聚集索引 íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
http://www.netcsharp.cn/showtopic-1290.aspxíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
聚集索引持续向上增长的需求íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
具体来说下面两个问题要求建立聚集索引的列最好是持续向上增长的íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
1、缓存的命中率问题。(需要从B+树的结构分析)íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
2、连续和不连续的磁盘 I/O 操作对性能的影响 。íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
细节参看这篇文章:íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
SQL Server 索引基础知识(5)----理解newid()和newsequentialid() íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
http://www.netcsharp.cn/showtopic-1375.aspxíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
至于,如果你的数据已经存在重复了,而且是不应该出现的,则可以参看下面这篇KB :  íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
如何删除 SQL Server 表中的重复行íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
http://support.microsoft.com/kb/139444/zh-cn  íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
非聚集索引提高性能的方法  íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
非聚集索引由于B+树的节点不是具体数据页,有时候由于这个原因,会导致非聚集索引甚至不如表遍历来的快,参看这篇文章中给的例子íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
http://www.netcsharp.cn/showtopic-1277.aspxíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
但是,非聚集索引有个特性,如果你要查询的内容,在非聚集索引中以及被覆盖到了,则不需要继续到聚集索引,或者RID中去寻找数据了,这时候就可以很大的提高性能,这就是 覆盖面(Covering) 的问题。íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
由于聚集索引叶子节点就是具体数据,所以 聚集索引的覆盖率是 100%, íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
通过提高覆盖面来提高性能的问题也就只有非聚集索引(Nonclustered Indexes)才存在。íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
当查询中所有的columns 都包括在index上时,我们说这个 index covers the query. Columns的顺序在此不重要íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
(Select 时候的顺序不重要,但是Index 建立的顺序可得小心了)。íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
在 SQL Server 2005 中,为了提高这种 Covering 带来的好处,甚至 可以通过将非键列添加到非聚集索引的叶级别来扩展非聚集索引的功能。íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
比如下面的脚本, 虽然我们是对 Title, Revision 建立的非聚集索引,但是这个非聚集索引的叶子节点上还包含 FileName 字段的信息。íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
USE AdventureWorks;íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
GOíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
CREATE INDEX IX_Document_Title      íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
ON Production.Document (Title, Revision)      íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
INCLUDE (FileName); 
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
下面的代码就是测试 Covering 的.我已经在每个查询使用的方式,逻辑读的个数都标在每个查询前面了。íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
SET STATISTICS IO ONíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
-- Turn Graphical Showplan ON (Ctrl+K)íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
USE CREDITíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
goíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
-- 逻辑读取144 次    Clustered Index ScaníÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
SELECT m.LastName, m.FirstName, m.Phone_NoíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
FROM dbo.Member AS m WITH (INDEX (0))íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
WHERE m.LastName LIKE '[S-Z]%'íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
goíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
--CREATE INDEX MemberLastName ON Member(LastName)íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
goíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
-- 逻辑读取6354 次 BookMark Lookup SELECT m.LastName, m.FirstName, m.Phone_NoíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
FROM dbo.Member AS m WITH (INDEX (MemberLastName))íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
WHERE m.LastName LIKE '[S-Z]%'íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
goíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
--CREATE INDEX NCLastNameCombo ON Member(LastName, FirstName, Phone_No)íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
goíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
-- 逻辑读取21 次  Index SeekíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
SELECT m.LastName, m.FirstName, m.Phone_NoíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
FROM dbo.Member AS míÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
WHERE m.LastName LIKE '[S-Z]%'íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
goíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
--CREATE INDEX NCLastNameCombo2 ON Member(FirstName, LastName, Phone_No)íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
goíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
-- 逻辑读取59 次    Index ScaníÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
SELECT m.LastName, m.FirstName, m.Phone_NoíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
FROM dbo.Member AS m WITH (INDEX (NCLastNameCombo2))íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
WHERE m.LastName LIKE '[S-Z]%'íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
goíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
-- If you want to clean up the indexes:íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
--DROP INDEX Member.MemberLastNameíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
--DROP INDEX Member.NCLastNameComboíÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
--DROP INDEX Member.NCLastNameCombo2
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ
íÉ ò±?Cçwww.netcsharp.cnMá!¿WeëßfÈ