zoukankan      html  css  js  c++  java
  • 索引碎片整理

    USE [DBA_Maintenance]
    IF EXISTS(SELECT 1 FROM sysobjects WHERE  xtype='P'  AND name = 'USP_Auto_IndexDefrag')
    BEGIN
        DROP PROCEDURE USP_Auto_IndexDefrag
    END
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE PROCEDURE [dbo].[USP_Auto_IndexDefrag]
    @Db_name nvarchar(256)
        WITH ENCRYPTION
    AS
        BEGIN
        SET NOCOUNT ON
    
        declare @dbname nvarchar(256)
            ,@dbname_cur nvarchar(256)
            ,@SchemaName nvarchar(256)
            ,@TableName Nvarchar(256)
            ,@IndexName Nvarchar(512)
            ,@PctFrag decimal
            ,@Defrag nvarchar(max)
        DECLARE @SQL_TMP_SUB NVARCHAR(MAX)
        DECLARE @SQL_TMP NVARCHAR(MAX)
    
        set @dbname=@Db_name
        set @Db_name=N'['+@Db_name+']'
    
            if exists(select 1 from sys.objects where object_id =object_id(N'#tmp')) Drop table #tmp;
            if exists(select 1 from sys.objects where object_id =object_id(N'#tmp_sub')) Drop table #tmp_sub;
        
        create table #tmp_sub(database_id int,dbname nvarchar(32),tablename nvarchar(128),index_type_desc nvarchar(128))
        create clustered index ix_sub_db_id_tb_name_indexname on #tmp_sub(database_id,tablename,index_type_desc)
        create table #tmp(database_id int,dbname nvarchar(256),tablename nvarchar(256),indexname nvarchar(256),type_desc nvarchar(128),schemaname nvarchar(256),avgfragment decimal)
        create clustered index ix_db_id_tb_name_indexname on #tmp(database_id,tablename,type_desc)    
    
        SET @SQL_TMP_SUB=N'USE' +@db_name+CHAR(13)+CHAR(10)+
        'insert into #tmp_sub(database_id,dbname,tablename,index_type_desc)
            select distinct c.database_id,c.name as dbname,b.name,''CLUSTERED''
             from 
                sys.dm_db_index_physical_stats(DB_ID('''+@dbname+'''),NULL,NULL,NULL,''SAMPLED'') as a
                join sys.tables as b on a.object_id=b.object_id 
                join sys.databases as c on a.database_id=c.database_id
                join sys.all_columns d on d.object_id =a.object_id 
                join sys.sysobjects e on d.object_id=e.id and e.xtype=''U''
                join sys.types f on d.user_type_id=f.user_type_id 
            where  b.type_desc=''USER_TABLE'' and b.is_ms_shipped=0 and (d.max_length =-1
                OR (f.name in (''image'',''text'',''ntext'',''xml'',''varbinary'',''binary'')))'+CHAR(13)+CHAR(10)+''
        EXEC SP_EXECUTESQL @SQL_TMP_SUB, N'@Db_name nvarchar(256),@dbname nvarchar(256)',@Db_name,@dbname
    
        SET @SQL_TMP=N' USE' +@db_name+CHAR(13)+CHAR(10)+
        'insert into #tmp(database_id,dbname,tablename,indexname,type_desc,schemaname,avgfragment)
            select  distinct d.database_id,d.name as dbname,c.name,b.name,b.type_desc,e.name,a.avg_fragmentation_in_percent 
            from sys.dm_db_index_physical_stats(DB_ID('''+@dbname+'''),NULL,NULL,NULL,''SAMPLED'') as a
                join sys.indexes as b on a.object_id=b.object_id and a.index_id=b.index_id 
                join sys.tables as c on a.object_id=c.object_id 
                join sys.databases as d on a.database_id=d.database_id
                join sys.schemas as e on c.schema_id=e.schema_id
                join sys.sysobjects f on c.object_id=f.id
                join sys.all_columns g on f.id=g.object_id
                join sys.types h on g.user_type_id=h.user_type_id
                where a.avg_fragmentation_in_percent >20
                 and c.type=''U'' and f.xtype=''U'' 
                 and c.is_ms_shipped=0 '+CHAR(13)+CHAR(10)+''
        EXEC SP_EXECUTESQL @SQL_TMP, N'@Db_name nvarchar(256),@dbname nvarchar(256)',@Db_name,@dbname
            ----------脱机重建索引
             declare @i_cur int=1
             declare @count int=0
                select @count=count(*)  from #tmp 
                    where  exists (select 1 from #tmp_sub b where database_id=b.database_id and tablename=b.tablename and type_desc=b.index_type_desc)
            if @count>=1
            begin
                while @i_cur<@count
                begin
                    select  @dbname_cur=dbname,@TableName=tablename,@IndexName=indexname,@SchemaName=schemaname,@PctFrag=avgfragment
                     from 
                        ( select row_number() over(order by indexname)rn,dbname,tablename,indexname,
                                 schemaname,avgfragment 
                               from #tmp 
                               where  exists (select 1 from #tmp_sub b where database_id=b.database_id and tablename=b.tablename and type_desc=b.index_type_desc)
                        )ta where rn=@i_cur
    
                        if @PctFrag between 20.0 and 40.0
                             begin
                              set @Defrag=N' ALTER INDEX ['+@IndexName+'] ON ['+@dbname_cur+'].['+@SchemaName+'].['+ @TableName +'] REORGANIZE'--重新组织索引页不删除索引
                              EXEC SP_EXECUTESQL @Defrag
                             end
                             else if @PctFrag>40.0
                             begin
                              SET @Defrag=N' ALTER INDEX ['+@IndexName+'] ON ['+@dbname_cur+'].['+@SchemaName+'].['+ @TableName +'] REBUILD WITH (ONLINE = OFF )'--脱机重建索引。
                              EXEC SP_EXECUTESQL @Defrag
                             end
                        set @i_cur=@i_cur+1
                end
            end
    
            ----------联机重建索引
            declare @n_count int=0
            declare @n_i int=1
    
            select @count=count(*) from #tmp 
                where not exists (select 1 from #tmp_sub b where database_id=b.database_id and tablename=b.tablename and type_desc=b.index_type_desc)
            if @count>=1
                begin
                    WHILE @n_i<@count
                        begin
                            select @dbname_cur=dbname,@TableName=tablename,@IndexName=indexname,@SchemaName=schemaname,@PctFrag=avgfragment
                                from (  select row_number() over(order by indexname)rn,dbname,tablename,indexname,
                                         schemaname,avgfragment 
                                       from #tmp 
                                       where not exists (select 1 from #tmp_sub b where database_id=b.database_id and tablename=b.tablename and type_desc=b.index_type_desc)
                                       )tb  where rn=@n_i
                                if @PctFrag between 20.0 and 40.0
                                     begin
                                      set @Defrag=N' ALTER INDEX ['+@IndexName+'] ON ['+@dbname_cur+'].['+@SchemaName+'].['+ @TableName +'] REORGANIZE'--重新组织索引页不删除索引
                                      EXEC SP_EXECUTESQL @Defrag
                                     end
                                     else if @PctFrag>40.0
                                     begin
                                      SET @Defrag=N' ALTER INDEX ['+@IndexName+'] ON ['+@dbname_cur+'].['+@SchemaName+'].['+ @TableName +'] REBUILD WITH (ONLINE = ON )'--联机重建索引。即不锁定表重新创建索引
                                      EXEC SP_EXECUTESQL @Defrag
                                     end
                        set @n_i=@n_i+1
                        end
                end
    
            truncate table #tmp
            truncate table #tmp_sub
            drop table #tmp
            drop table #tmp_sub
     
        SET NOCOUNT OFF
    
    END
  • 相关阅读:
    Intellij IDEA 打开文件tab数量限制的调整
    Mysql处理中文乱码的问题
    MIT算法导论笔记
    算法导论-排序(一)-插入排序、归并排序
    leetcode题解:Search for a Range (已排序数组范围查找)
    leetcode 题解:Merge Sorted Array(两个已排序数组归并)
    leetcode题解:Construct Binary Tree from Inorder and Postorder Traversal(根据中序和后序遍历构造二叉树)
    leetcode题解:Construct Binary Tree from Preorder and Inorder Traversal (根据前序和中序遍历构造二叉树)
    c++11 std::prev、std::next、std::advance与auto 使用
    (转)指针的引用(*&)与指针的指针(**)
  • 原文地址:https://www.cnblogs.com/zhaowenzhong/p/5164049.html
Copyright © 2011-2022 走看看