`
zznj1123
  • 浏览: 123227 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

SQLServer索引碎片和解决方法

阅读更多

毫无疑问,给表添加索引是有好处的,你要做的大部分工作就是维护索引,在数据更改期间索引可能产生碎片,所以一些维护是必要的。碎片可能是你查询产生性能问题的来源。

那么到底什么是索引碎片呢?索引碎片实际上有2种形式:外部碎片和内部碎片。不管哪种碎片基本上都会影响索引内页的使用。这也许是因为页的逻辑顺序错误(即外部碎片)或每页存储的数据量少于数据页的容量(内部错误)。无论索引产生了哪种类型的碎片,你都会因为它而面临查询的性能问题。

外部碎片

当索引页不在逻辑顺序上时就会产生外部碎片。索引创建时,索引键按照逻辑顺序放在一组索引页上。当新数据插入索引时,新的键可能放在存在的键之间。为了让新的键按照正确的顺序插入,可能会创建新的索引页来存储需要移动的那些存在的键。这些新的索引页通常物理上不会和那些被移动的键原来所在的页相邻。创建新页的过程会引起索引页偏离逻辑顺序。

下面的例子将比实际的言论更加清晰的解释这个概念。
假定在任何另外的数据插入你的表之前存在索引上的结构如下

(注:下面图片里应该是7和8,原文里是6和8):


INSERT语句往索引里添加新的数据,假定添加的是5INSERT将引起新页创建,为了给5在原来的页上留出空间,78被移到了新页上。这个创建将引起索引页偏离逻辑顺序。


在有特定搜索或者返回无序结果集的查询的情况下,偏离顺序的索引页不会引起问题。对于返回有序结果集的查询,搜索那些无序的索引页需要进行额外的处理。有序结果集的例子如查询返回410之间的记录。为了返回78,查询不得不进行额外的页切换。虽然一个额外的页切换在一个长时间运行里是无关紧要的,然而想象一下一个有好几百页偏离顺序的非常大的表的情形。

内部碎片

当索引页没有用到最大量时就产生了内部碎片。虽然在一个有频繁数据插入的应用程序里这也许有帮助,然而设置一个fill factor(填充因子)会在索引页上留下空间,服务器内部碎片会导致索引尺寸增加,从而在返回需要的数据时要执行额外的读操作。这些额外的读操作会降低查询的性能。

怎样确定索引是否有碎片?

SQLServer提供了一个数据库命令――DBCC SHOWCONTIG――来确定一个指定的表或索引是否有碎片。
DBCC SHOWCONTIG
数据库平台命令,用来显示指定的表的数据和索引的碎片信息。

DBCC SHOWCONTIG 权限默认授予 sysadmin固定服务器角色或 db_owner db_ddladmin固定数据库角色的成员以及表的所有者且不可转让。
语法(SQLServer2000

DBCC SHOWCONTIG
[ ( { table_name | table_id| view_name | view_id }
[ , index_name | index_id ]
)
]
[ WITH { ALL_INDEXES
| FAST [ , ALL_INDEXES ]
| TABLERESULTS [ , { ALL_INDEXES } ]
[ , { FAST | ALL_LEVELS } ]
}
]


语法(SQLServer7.0

DBCC SHOWCONTIG
[ ( table_id [,index_id ]
)
]



示例:
显示数据库里所有索引的碎片信息
SET NOCOUNT ON
USE pubs
DBCC SHOWCONTIG WITH ALL_INDEXES


GO


显示指定表的所有索引的碎片信息
SET NOCOUNT ONUSE pubs
DBCC SHOWCONTIG (authors) WITH ALL_INDEXES

GO


显示指定索引的碎片信息
SET NOCOUNT ON
USE pubs
DBCC SHOWCONTIG (authors,aunmind)

GO


结果集
DBCC SHOWCONTIG将返回扫描页数、扫描扩展盘区数、遍历索引或表的页时,DBCC 语句从一个扩展盘区移动到其它扩展盘区的次数、每个扩展盘区的页数、扫描密度(最佳值是指在一切都连续地链接的情况下,扩展盘区更改的理想数目)。

DBCC SHOWCONTIG 正在扫描 'authors' ...
: 'authors'1977058079);
索引 ID: 1,数据库 ID: 5
已执行 TABLE 级别的扫描。
- 扫描页数.....................................: 1

- 扫描扩展盘区数...............................: 1
- 扩展盘区开关数...............................: 0
- 每个扩展盘区上的平均页数.....................: 1.0
- 扫描密度[最佳值:实际值]....................: 100.00%1:1
- 逻辑扫描碎片.................................: 0.00%

- 扩展盘区扫描碎片.............................: 0.00%
- 每页上的平均可用字节数.......................: 6010.0
- 平均页密度(完整)...........................: 25.75%

DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

 


寻找什么

扫描页数:如果你知道行的近似尺寸和表或索引里的行数,那么你可以估计出索引里的页数。看看扫描页数,如果明显比你估计的页数要高,说明存在内部碎片。

扫描扩展盘区数:用扫描页数除以8,四舍五入到下一个最高值。该值应该和DBCC SHOWCONTIG返回的扫描扩展盘区数一致。如果DBCC SHOWCONTIG返回的数高,说明存在外部碎片。碎片的严重程度依赖于刚才显示的值比估计值高多少。

扩展盘区开关数:该数应该等于扫描扩展盘区数减1。高了则说明有外部碎片。

每个扩展盘区上的平均页数:该数是扫描页数除以扫描扩展盘区数,一般是8。小于8说明有外部碎片。

扫描密度[最佳值:实际值]:DBCC SHOWCONTIG返回最有用的一个百分比。这是扩展盘区的最佳值和实际值的比率。该百分比应该尽可能靠近100%。低了则说明有外部碎片。

逻辑扫描碎片:无序页的百分比。该百分比应该在0%到10%之间,高了则说明有外部碎片。

扩展盘区扫描碎片:无序扩展盘区在扫描索引叶级页中所占的百分比。该百分比应该是0%,高了则说明有外部碎片。

每页上的平均可用字节数:所扫描的页上的平均可用字节数。越高说明有内部碎片,不过在你用这个数字决定是否有内部碎片之前,应该考虑fill factor(填充因子)。

平均页密度(完整):每页上的平均可用字节数的百分比的相反数。低的百分比说明有内部碎片。

备注

DBCC SHOWCONTIG实际上仅对那些大表有用。小表显示的结果根本不符合正常标准,因为他们也许没有由多于8个的页面组成。你在查看小表上执行DBCC SHOWCONTIG的结果时应该忽略一些结果。在处理小表时只需关心扩展盘区开关数、逻辑扫描碎片、每页上的平均可用字节数、平均页密度(完整)。

DBCC SHOWCONTIG默认输出的结果是:扫描页数、扫描扩展盘区数、扩展盘区开关数、每个扩展盘区上的平均页数、扫描密度[最佳值:实际值]、逻辑扫描碎片、扩展盘区扫描碎片、每页上的平均可用字节数、平均页密度(完整)。可以用FASTTABLERESULTS选项来控制这个输出结果。

FAST选项指定执行索引的快速扫描,输出结果是最小的,该选项不读索引的叶或数据页且只返回扫描页数、扫描扩展盘区数、扫描密度[最佳值:实际值]、逻辑扫描碎片。

TABLERESULTS选项将用行集的形式显示信息,将返回扩展盘区开关数、扫描密度[最佳值:实际值]、逻辑扫描碎片、扩展盘区扫描碎片、每页上的平均可用字节数、平均页密度(完整)。

如果既指定FAST选项又指定TABLERESULTS选项,那么将返回对象名、对象ID、索引名、索引ID,页数、扩展盘区开关数、扫描密度[最佳值:实际值]和逻辑扫描碎片。

ALL_INDEXES选项将显示指定表和试图的所有索引的结果,即使指定了一个索引。

ALL_LEVELS选项指定是否为所处理的每个索引的每个级别产生输出(默认只输出索引的页级或表数据级的结果),并且只能与 TABLERESULTS 选项一起使用。

解决碎片问题

一旦你确定表或索引有碎片问题,那么你有4个选择去解决那些问题:
  • 删除并重建索引
  • 使用DROP_EXISTING子句重建索引
  • 执行DBCC DBREINDEX
  • 执行DBCC INDEXDEFRAG
尽管每一个技术都能达到你整理索引碎片的最终目的,但各有各的优缺点。

删除并重建索引

DROP INDEXCREATE INDEXALTER TABLE来删除并重建索引有些缺陷包括在删除重建期间索引会消失。在索引删除重建时,对于查询它不在可用,查询性能也许会受到明显的影响,直到重建索引为止。另一个潜在的缺陷是当都请求索引的时候会引起阻塞,直到重建索引为止。通过其他的处理也能解决阻塞,就是索引被使用的时候不删除索引。另一个主要的缺陷是在用DROP INDEXCREATE INDEX重建聚集索引时会引起非聚集索引重建两次。删除聚集索引时非聚集索引的行指针会指向数据堆,聚集索引重建时非聚集索引的行指针又会指回聚集索引的行位置。

删除并重建索引的确有一个好处就是通过重新排序索引页,使索引页紧凑并删除不需要的索引页来完全重建索引。你也许需要考虑那些内部和外部碎片都很高的情况下才使用,以使那些索引回到它们应该在的位置。

使用DROP_EXISTING子句重建索引

为了避免在重建聚集索引时表上的非聚集索引重建两次,可以使用带DROP_EXISTING子句的CREATE INDEX语句。这个子句会保留聚集索引键值,以避免非聚集索引重建两次。和删除并重建索引一样,该方法也可能会引起阻塞和索引消失的问题。该方法的另一个缺陷是也强迫你去分别发现和修复表上的每一个索引。

除了和上一个方法一样的好处之外,该方法的好处是不必重建非聚集索引两次。这样可以对那些带约束的索引提供正确的索引定义以符合约束的要求。

执行DBCC DBREINDEX

DBCC DBREINDEX类似于第二种方法,但它物理地重建索引,允许SQLServer给索引分配新页来减少内部和外部碎片。DBCC DBREINDEX也能动态的重建带约束的索引,不象第二种方法。

DBCC DBREINDEX的缺陷是会遇到或引起阻塞问题。DBCC DBREINDEX是作为一个事务来运行的,所以如果在完成之前中断了,那么你会丢失所有已经执行过的碎片。

执行DBCC INDEXDEFRAG

DBCC INDEXDEFRAG(在SQLServer2000中可用)按照索引键的逻辑顺序,通过重新整理索引里存在的叶页来减少外部碎片,通过压缩索引页里的行然后删除那些由此产生的不需要的页来减少内部碎片。它不会遇到阻塞问题但它的结果没有其他几个方法彻底。这是因为DBCC INDEXDEFRAG跳过了锁定的页且不使用任何新页来重新排序索引。如果索引的碎片数量大的话你也许会发现DBCC INDEXDEFRAG比重建索引花费的时间更长。DBCC INDEXDEFRAG比其他方法的确有好处的是在其他过程访问索引时也能进行碎片整理,不会引起其他方法的阻塞问题。

分享到:
评论

相关推荐

    SQL_Server2005索引碎片分析和解决方法

    ### SQL Server 2005 索引碎片分析与解决方法 #### 一、索引碎片的概念 在SQL Server 2005中,索引是提高查询效率的重要手段之一。然而,随着数据的增删改查操作,索引可能会出现碎片化现象。碎片化的索引会导致...

    SqlServer性能优化高效索引指南.pdf

    索引的重整可以解决索引碎片的问题,索引的重建可以解决索引损坏的问题,索引的压缩可以减少存储空间。 此外,本指南还涵盖了其他一些重要的知识点,例如数据类型的选择、索引的最大列数、索引的最大字节数、数据...

    提高SQL Server性能,可通过DBCC DBREINDEX重建索引

    通过使用`DBCC DBREINDEX`命令,我们可以有效地解决SQL Server中的索引碎片化问题,进而提高查询性能。值得注意的是,索引重建是一个资源密集型操作,应该尽量避免在业务高峰期执行。此外,合理设置填充因子也是优化...

    SQL Server索引设计和调优技术大全

    ### SQL Server索引设计与调优技术大全 #### 一、引言 SQL Server作为一款广泛使用的数据库管理系统,其性能的高低直接影响着企业的业务效率。其中,索引的设计与优化是提升SQL Server性能的关键环节之一。合理的...

    sql server 索引设计与优化

    ### SQL Server 索引设计与优化 #### 索引的重要性 ...通过上述内容的学习,读者不仅能够深刻理解SQL Server索引的设计原理和技术细节,还能够掌握一系列实用的索引优化技巧,从而显著提高数据库系统的整体性能。

    sql server健康检查脚本

    SQL Server健康检查脚本通常包含一系列查询,这些查询旨在收集关于服务器状态的关键信息,包括但不限于CPU使用率、内存使用情况、磁盘I/O性能、数据库事务日志的增长、备份状况、索引碎片、锁和阻塞等。通过执行这些...

    SQLSERVER日志分析工具

    SQLSERVER日志分析工具是一种专门针对Microsoft SQL Server数据库系统设计的实用软件,旨在帮助数据库管理员和开发者有效地管理和解析SQL Server的日志数据。日志分析在数据库管理中扮演着至关重要的角色,因为它能...

    SQL Server索引设计与调优

    本篇文章将深入探讨SQL Server索引的基本概念、类型、设计原则以及优化策略。 首先,我们需要了解索引的类型。SQL Server支持两种主要的索引类型:B树索引(包括主键和唯一索引)和哈希索引。B树索引分为聚集索引和...

    SQL Server 2000系统表地图.rar_sql_sql server_sql server 2000_多变量

    系统表是SQL Server内部结构的核心组成部分,它们存储了关于数据库、索引、用户、权限等所有元数据信息。理解这些系统表对于数据库管理员进行性能优化、故障排查和管理操作至关重要。 在SQL Server 2000中,系统表...

    SQLServer索引+性能优化.rar

    在这个名为"SQLServer索引+性能优化.rar"的压缩包中,包含了一系列关于SQL Server性能优化和索引原理的PPT材料,适合初学者进行深入学习。 首先,让我们来了解索引的基本概念。在数据库中,索引就像是书籍的目录,...

    SQL Server2000教程 课件

    理解锁和事务对性能的影响,以及索引碎片的处理。 12. **报表服务**:SQL Server 2000的报表服务允许创建、发布和管理各种类型的报表,结合数据可视化工具,为企业提供决策支持。 通过学习《SQL Server 2000教程》...

    SQL Server 2008 性能和可扩展性白皮书

    3. SQL Server Management Studio (SSMS):集成的开发和管理工具,包含性能监视器和性能计数器,可用于识别和解决性能问题。 4. Resource Governor:允许管理员控制服务器资源的分配,限制特定工作负载的资源消耗,...

    sqlserver 一堆学习文档

    Oracle和SqlServer系统表操作差异对比.docx SQL_Server2005索引碎片分析和解决方法.doc SQLSERVER存储过程大总结.doc SQL中各种索引.docx 看懂SqlServer查询计划 .docx 经典SQL语句大全.doc

    造成mdf文件过大的原因

    要知道是否发生了索引碎片,可以执行下面的 SQL 语句: ``` SELECT object_name(dt.object_id) Tablename,si.name IndexName,dt.avg_fragmentation_in_percent AS ExternalFragmentation,dt.avg_page_space_used_in...

    经典SQLServer操作脚本

    "经典SQL Server操作脚本"这个主题涵盖了一系列实用的技巧和方法,包括处理日期、字符、排序以及行列转换等方面的知识。这些脚本通常经过实战检验,能够帮助数据库管理员和开发者更高效地完成日常工作。 1. **日期...

    SQL_Server索引设计和调优技巧大全

    ### SQL Server索引设计和调优技巧大全 #### 一、引言 SQL Server作为一款广泛使用的数据库管理系统,其性能的高低直接影响着企业的业务效率。其中,索引的设计与优化是提升SQL Server性能的关键手段之一。本文将...

    SQL Server学习教程

    7. 故障转移群集和高可用性:SQL Server支持故障转移群集实例和Always On可用性组,提供高可用性和灾难恢复解决方案。理解如何配置和管理这些特性,可以确保业务连续性。 8. 监控与性能调优:通过SQL Server ...

Global site tag (gtag.js) - Google Analytics