SQL Server 索引的自动维护 <第十三篇>

在有大量事务的数据库中,表和索引随着时间的推移而碎片化。因此,为了增进性能,应该定期检查表和索引的碎片,并对具有大量碎片的进行整理。

  1、确定当前数据库中所有需要分析碎片的表。

  2、确定所有表和索引的碎片。

  3、考虑一下因素以确定需要进行碎片整理的表和索引。

  •   高的碎片水平-avg_fragmentation_in_percent大于20%;
  •   不是非常小的表或索引-也就是page_count大于8的;

  4、整理具有大量碎片的表和索引;

  这里给出一个样板SQL存储过程,它执行以下操作;

  •   遍历系统上的所有数据库并确认符合碎片条件的每个数据库中表上的索引,并将它们保存到一个临时表中;
  •   根据碎片水平,重新整理碎片较少的索引并重建碎片很多的索引。

CREATE PROCEDURE IndexDefrag
AS

DECLARE @DBName NVARCHAR(255)
    ,@TableName NVARCHAR(255)
    ,@SchemaName NVARCHAR(255)
    ,@IndexName NVARCHAR(255)
    ,@PctFrag DECIMAL

DECLARE @Defrag NVARCHAR(MAX)

IF EXISTS (SELECT * FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N‘#Frag‘))
    DROP TABLE #Frag

CREATE TABLE #Frag
(DBName NVARCHAR(255)
,TableName NVARCHAR(255)
,SchemaName NVARCHAR(255)
,IndexName NVARCHAR(255)
,AvgFragment DECIMAL)

EXEC sp_msforeachdb ‘INSERT INTO #Frag (
    DBName,
    TableName,
    SchemaName,
    IndexName,
    AvgFragment
) SELECT  ‘‘?‘‘ AS DBName
       ,t.Name AS TableName
       ,sc.Name AS SchemaName
       ,i.name AS IndexName
       ,s.avg_fragmentation_in_percent
FROM    ?.sys.dm_db_index_physical_stats(DB_ID(‘‘?‘‘), NULL, NULL,
                                       NULL, ‘‘Sampled‘‘) AS s
        JOIN ?.sys.indexes i
        ON s.Object_Id = i.Object_id
           AND s.Index_id = i.Index_id
        JOIN ?.sys.tables t
        ON i.Object_id = t.Object_Id
        JOIN ?.sys.schemas sc
        ON t.schema_id = sc.SCHEMA_ID
WHERE s.avg_fragmentation_in_percent > 20
AND t.TYPE = ‘‘U‘‘
AND s.page_count > 8
ORDER BY TableName,IndexName‘

DECLARE cList CURSOR
FOR SELECT * FROM #Frag

OPEN cList
FETCH NEXT FROM cList
INTO @DBName, @TableName,@SchemaName,@IndexName,@PctFrag
WHILE @@FETCH_STATUS = 0
BEGIN
    IF @PctFrag BETWEEN 20.0 AND 40.0
    BEGIN
        SET @Defrag = N‘ALTER INDEX ‘ + @IndexName + ‘ ON ‘ + @DBName + ‘.‘ + @SchemaName + ‘.‘ + @TableName + ‘ REORGANIZE‘
        EXEC sp_executesql @Defrag
        PRINT ‘Reorganize index: ‘ + @DBName + ‘.‘ + @SchemaName + ‘.‘ + @TableName +‘.‘ + @IndexName
    END
    ELSE IF @PctFrag > 40.0
    BEGIN
        SET @Defrag = N‘ALTER INDEX ‘ + @IndexName + ‘ ON ‘ + @DBName + ‘.‘ + @SchemaName + ‘.‘ + @TableName + ‘ REBUILD‘
        EXEC sp_executesql @Defrag
        PRINT ‘Rebuild index: ‘+ @DBName + ‘.‘ + @SchemaName + ‘.‘ + @TableName +‘.‘ + @IndexName
    END

    FETCH NEXT FROM cList
    INTO @DBName, @TableName,@SchemaName,@IndexName,@PctFrag

END
CLOSE cList
DEALLOCATE cList

DROP TABLE #Frag

  为了自动化碎片分析过程,可以从SQL Server企业管理器中用以下简单的步骤创建一个SQL Server任务。

  1、开启SQL Server代理;

  

  2、打开Management Studio,右键单击,选择新建=》任务;

  

  3、在新建任务对话框的“常规”页面中,输入任务名称和其他细节:

  

  4、在新建任务对话框的“步骤”页面中,单击“新建”并输入用户数据库的SQL命令。

  

  5、在新建任务步骤对话框“高级”页面上,输入报告碎片分析结果的输出文件名称:

  

  6、单击“确定”按钮,返回新建作业对话框;

  7、在新建任务对话框“计划”页面,单击“新建计划”,并输入运行SQL Server任务的合适计划:

  

  安排这个存储过程在非高峰执行。为了确定数据库的数据库模式,记录整天的SQL Server:SQL Statistics\Batch Requests/sec性能计数器,它将展示数据库负载的波动。

  8、单击“确定”按钮,返回新建任务对话框。

  9、输入所有信息后,单击新建任务对话框中的“确定”按钮创建SQL Server任务。创建计划在一个固定时间间隔(每周)运行sp_indexDefrag存储过程的SQL Server任务。

  10、确保SQL Server代理运行,这样SQL Server任务将自动根据设置的计划运行。

  这个SQL任务将在每个星期天的凌晨1点分析每个数据库并且进行碎片整理。

SQL Server 索引的自动维护 <第十三篇>,布布扣,bubuko.com

时间: 2024-10-24 11:33:57

SQL Server 索引的自动维护 <第十三篇>的相关文章

SQL Server 索引知识-应用,维护

创建聚集索引 a索引键最好唯一(如果不唯一会隐形建立uniquier列(4字节)确保唯一,也就是这列都会复制到所有非聚集索引中) b聚集索引列所占空间应尽量小(否则也会使非聚集索引的空间变大) c聚集索引应固定,不能随便改动(否则会引起分页,碎片,非聚集索引被迫修改等一些列问题) d聚集索引键一般与主键(primary key)分开(基于方便业务调整,如业务逻辑存储数据与clustered index key一致且不会改变,则主键可为聚集索引) 应用实例: 选择聚集键时,尽量避免因插入引起的分页

SQL Server 索引 之 书签查找 &lt;第十一篇&gt;

一.书签查找的概念 书签可以帮助SQL Server快速从非聚集索引条目导向到对应的行,其实这东西几句话我就能说明白. 如果表有聚集索引(区段结构),那么书签就是从非聚集索引找到聚集索引后,利用聚集索引定位到数据.此处的书签就是聚集索引.如果表没有聚集索引(堆结构).那么扫描非聚集索引后,通过RID定位到数据,那么此处书签就是RID. 所谓的书签查找,就是通过聚集索引,然后利用聚集索引或RID定位到数据. 不论表示堆结构还是区段结构,数据的存放都是数据库文件的某文件->某页->某行,因此定位数

SQL Server 分区方案自动维护脚本

CREATE PROC Proc_partition_dealAS DECLARE @LatestValue DATETIME, @LastValue DATETIME, @EarlValue DATETIME, @differ INT, @New_Range_Value DATETIME, @fileGroupName VARCHAR(200), @sql VARCHAR(1000), @P_Sch_Name VARCHAR(100), @P_Fun_Name VARCHAR(100), @P

SQL Server 索引维护:系统常见的索引问题

在很多系统中,比如本人目前管理的数据库,索引经常被滥用,甚至使用DTA(数据库引擎优化顾问)来成批创建索引(DTA目前个人认为它的真正用处应该是在发现缺失的统计信息,在以前的项目中,用过一次DTA,里面提示了很多列缺少统计信息,后来在不改动其他操作的前提下,把这些统计信息手动建上去,性能提升非常明显.关于统计信息将另开文章介绍).一个表甚至有20多个索引(索引的数量并没有标准,但是要尽量合理,每个索引都应该能支撑大量查询或者增删改中的查询功能才有存在价值).索引过多带来了服务器的沉重压力,有这么

SQL Server索引的维护 - 索引碎片、填充因子 &lt;第三篇&gt;

实际上,索引的维护主要包括以下两个方面: 页拆分 碎片 这两个问题都和页密度有关,虽然两者的表现形式在本质上有所区别,但是故障排除工具是一样的,因为处理是相同的. 对于非常小的表(比64KB小得多),一个区中的页面可能属于多余一个的索引或表---这被称为混合区.如果数据库中有太多的小表,混合区帮助SQL Server节约磁盘空间. 随着表(或索引)增长并且请求超过8个页面,SQL Server创建专用于该表(或索引)的区并且从该区中分配页面.这样一个区被称为统一区,它可以为多达8个相同表或索引的

转: SQL Server索引的维护 - 索引碎片、填充因子

转:http://www.cnblogs.com/kissdodog/archive/2013/06/14/3135412.html 实际上,索引的维护主要包括以下两个方面: 页拆分 碎片 这两个问题都和页密度有关,虽然两者的表现形式在本质上有所区别,但是故障排除工具是一样的,因为处理是相同的. 对于非常小的表(比64KB小得多),一个区中的页面可能属于多余一个的索引或表---这被称为混合区.如果数据库中有太多的小表,混合区帮助SQL Server节约磁盘空间. 随着表(或索引)增长并且请求超过

SQL Server索引设计 &lt;第五篇&gt;

SQL Server索引的设计主要考虑因素如下: 检查WHERE条件和连接条件列: 使用窄索引: 检查列的选择性: 检查列的数据类型: 考虑列顺序: 考虑索引类型(聚集索引OR非聚集索引): 一.检查WHERE条件列和链接条件列 当一个查询提交到SQL Server时,查询优化器尝试为查询中引用的所有表查找最佳的数据访问机制.下面列出查询优化器针对WHERE和连接的工作方式: 优化器识别WHERE子句和连接条件中包含的列. 接着优化器检查这些列上的索引. 优化器通过从索引上维护的统计确定子句的选

SQL Server索引 (原理、存储)聚集索引、非聚集索引、堆 &lt;第一篇&gt;

一.存储结构 在SQL Server中,有许多不同的可用排列规则选项. 二进制:按字符的数字表示形式排序(ASCII码中,用数字32表示空格,用68表示字母"D").因为所有内容都表示为数字,所以处理起来速度最快,遗憾的是,它并不总是如人们所想象,在WHERE子句中进行比较时,使用该选项会造成严重的混乱. 字典顺序:这种排序方式与在字典中看到的排序方式一样,但是少有不同,可以设置大量不同的额外选项来决定是否区分大小写.音调和字符集. 1.平衡树(B-树) 平衡树或B-树仅是提供了一种以

SQL Server索引技术

索引的分类说明 聚集索引:基于记录在数据表内的排序和存储位置.因为数据的物理排序只能有一种方式,所以在一个表中,只能有一个字段设为聚集索引. 非聚集索引:将索引建立在索引页上,查询时从索引中找到记录存放的位置. 唯一索引:当字段设置了唯一索引,那么不同记录的同一字段就是唯一的.当数据表中创建了主键后,数据库会自动为该主键创建唯一索引. 复合索引:将多个字段组合起来作为索引,称为复合索引.只有用到复合索引的第一个字段或整个复合索引字段作为条件查询才会用到该索引. 包含性列索引:创建索引时,最多的字