zoukankan      html  css  js  c++  java
  • Sqlserver——日常维护——定期重建索引

    大致的重建范围是 逻辑密度碎片>30以及页码总数>8以上的数据库索引碎片

    直接上代码(附带生成执行完之后生成日志记录表)

    SET QUOTED_IDENTIFIER ON
    SET ANSI_NULLS ON
    GO
     
    Create PROCEDURE [dbo].[p_index_rebuild_test]
    AS
     
     
     
    DECLARE @DatabaseName NVARCHAR(255)--数据库名
    DECLARE @SchemaName NVARCHAR(255)--架构名
    DECLARE @TableName NVARCHAR(255)--表名
    DECLARE @IndexName NVARCHAR(255)--索引名
    DECLARE @IndexType NVARCHAR(255)--索引类型
    DECLARE @IndexColums NVARCHAR(MAX)--索引列清单
    DECLARE @DuringTime INT--重建时间
    DECLARE @Before_avg_fragmentation_in_percent DECIMAL(19,8)--重建前的逻辑扫描碎片
    DECLARE @After_avg_fragmentation_in_percent DECIMAL(19,8)--重建后的逻辑扫描碎片
     
     
    SET XACT_ABORT ON 
    SET NOCOUNT ON 
     
    -----------定期重建索引执行计划--------
     
    BEGIN TRAN
     
    ----------1、创建记录表,写入本次索引重构的日志
    --日志表名
    DECLARE @LogTableName NVARCHAR(255)='ReBuildIndexLog_'+CONVERT(VARCHAR(100),GETDATE(),112)
     
    DECLARE @sql NVARCHAR(MAX)=''
     
     
     
    IF EXISTS(SELECT * FROM sys.objects WHERE object_id=OBJECT_ID(@LogTableName))
    BEGIN
     
    SET @sql='drop table '+@LogTableName
    EXEC (@sql)
     
    END
     
    SET @sql ='Create Table '+@LogTableName+'
    		   (
    		   DatabaseName nvarchar(255),
    		   SchemaNam nvarchar(255),
    		   TableName nvarchar(255),
    		   IndexName nvarchar(255),
    		   IndexType nvarchar(255),
    		   IndexColums nvarchar(255),
    		   DuringTime int,
    		   Before_avg_fragmentation_in_percent DECIMAL(19,8),
    		   After_avg_fragmentation_in_percent DECIMAL(19,8)
    		   ) 
    		   '
    EXEC (@sql);
    SELECT @sql
     
    ---------2、查询逻辑扫描碎片大于30,并且数据页大于8以上的数据表,并插入到临时表中
     
    SELECT  database_id,
    		object_id,
    		index_id,
    		index_type_desc,
    		IDENTITY(INT,1,1) AS ID,
    		partition_number
    		INTO #Temp_A
    FROM    sys.dm_db_index_physical_stats(DB_ID(DB_NAME()), NULL, NULL, NULL,
                                           'Sampled')
    WHERE   avg_fragmentation_in_percent > 30
            AND page_count > 8;
     
     
     
    --------3、循环所有的临时表记录
     
    DECLARE @i INT =1
    DECLARE @q INT =(SELECT MAX(ID) FROM #Temp_A)
    DECLARE @Btime DATETIME--开始时间
    DECLARE @Etime DATETIME--结束时间
    DECLARE @IndexID INT--索引ID
    DECLARE @PartitionNum INT --分区编号
    WHILE @i<=@q
    BEGIN
    SELECT  @DatabaseName = d.name ,--数据库名
            @SchemaName = 'dbo' ,--架构名
            @TableName = t.name ,--表名
    		@IndexID=a.index_id,--索引ID
            @IndexName = i.name ,--索引名
            @IndexType = a.index_type_desc,--索引类型
    		@PartitionNum=a.partition_number,--分区编号
            @IndexColums = ( SELECT c.name + ','
                             FROM   sys.index_columns ic
                                    INNER JOIN sys.columns c ON ic.object_id = c.object_id
                                                                AND ic.index_column_id = c.column_id
                             WHERE  ic.object_id = a.object_id
                                    AND ic.index_id = a.index_id
                           FOR
                             XML PATH('')
                           )--索引列
    FROM    #Temp_A a
            INNER JOIN sys.databases d ON a.database_id = d.database_id
            INNER JOIN sys.tables t ON a.object_id = t.object_id
            INNER JOIN sys.indexes i ON a.object_id = i.object_id
                                        AND a.index_id = i.index_id
    		WHERE a.ID=@i
     
    SET @Btime=GETDATE()
     
    --PRINT '循环:'+CONVERT(NVARCHAR(20),@i)
     
     
    SET @Before_avg_fragmentation_in_percent = ( SELECT TOP 1 avg_fragmentation_in_percent
                                                 FROM   sys.dm_db_index_physical_stats(DB_ID(@DatabaseName),
                                                                  OBJECT_ID(@TableName),
                                                                  @IndexID, @PartitionNum,
                                                                  'Sampled')
                                               );
    SET @sql='alter index '+@IndexName+' on '+@TableName+' REBUILD With(FILLFACTOR=90)'
     
    EXEC(@sql);
     
     
    SET @After_avg_fragmentation_in_percent = ( SELECT TOP 1 avg_fragmentation_in_percent
                                                 FROM   sys.dm_db_index_physical_stats(DB_ID(@DatabaseName),
                                                                  OBJECT_ID(@TableName),
                                                                  @IndexID, @PartitionNum,
                                                                  'Sampled')
                                               );
     
     
    SET @Etime=GETDATE()
     
    SET @DuringTime=DATEDIFF(MILLISECOND,@Btime,@Etime)
     
     
     
    SET @sql='insert into '+@LogTableName+'
    		  select '+CHAR(39)+@DatabaseName+CHAR(39)+',
    				 '+CHAR(39)+@SchemaName+CHAR(39)+',
    				 '+CHAR(39)+@TableName+CHAR(39)+',
    				 '+CHAR(39)+@IndexName+CHAR(39)+',
    				 '+CHAR(39)+@IndexType+CHAR(39)+',
    				 '+CHAR(39)+@IndexColums+CHAR(39)+',
    				 '+CHAR(39)+CONVERT(NVARCHAR(255),@DuringTime)+CHAR(39)+',
    				 '+CHAR(39)+CONVERT(NVARCHAR(255),@Before_avg_fragmentation_in_percent)+CHAR(39)+',
    				 '+CHAR(39)+CONVERT(NVARCHAR(255),@After_avg_fragmentation_in_percent)+CHAR(39)+'
    				 '
    EXEC(@sql)
     
     
    SET @i=@i+1;
    END
     
     
     
     
    COMMIT TRAN
     
     
     
     
     
     
    GO
    

     来源:https://blog.csdn.net/qq_40205468/article/details/87289730

  • 相关阅读:
    041.PGSQL-pgsql常用命令-查看日志文件大小、数据目录、运行日志相关配置、当前lsn
    041.PGSQL-pgsql时间日期错误问题,原来是系统时间问题,使用远程的NTP时间服务器来提供时间的话,需要使用timedatectl设置将NTP时间同步开启。
    040.PGSQL-备份和恢复-增量备份-创建基础备份
    039.PGSQL-备份和恢复-增量备份-开启wal归档、并设置定时清理备份之后的wal文件
    037.PGSQL-事务 savepoint 保存点、rollback to 回滚
    硬件黑客之无线电安全 --- Proxmark3 RDV4 套件
    我有一个想法。。。
    硬件嘿客之嘿客仓库
    WPA GPU基准测试
    什么是家用路由器,带你重新认识一下
  • 原文地址:https://www.cnblogs.com/gguozhenqian/p/14339951.html
Copyright © 2011-2022 走看看