2012-01-25 41 views
0

我有一個維護任務失敗,因爲數據庫中有一些索引的類型不允許聯機重建索引。脫機在我的行業中不是一種選擇,所以我必須創建自己的T-SQL任務,在特定索引上重建索引。數據庫很大,有許多表和索引,那麼有沒有辦法查詢系統中所有索引及其數據類型?如何檢索數據庫中的所有索引及其SQL Server 2005中的數據類型?

+0

很肯定[這兩種方案我在這裏提到](http://dba.stackexchange.com/questions/11389/is-staggering 「HasBlobs」 標誌-reindexing-jobs-a-good-strategy-mssql/11390#comment16991_11390)考慮到這一點。 –

回答

0

這將顯示所有指數中的所有列,包括像堆「基表」和聚簇索引的列和所有INCLUDE列,以及:

select o.name as [object_name], 
    ix.name as [index_name], 
    coalesce(c.name,cc.name) as [column_name], 
    t.name as [type_name], 
    coalesce(c.max_length, cc.max_length) as max_length 
from sys.indexes ix 
join sys.objects o 
    on ix.object_id = o.object_id 
left join sys.index_columns ic 
    on ix.object_id = ic.object_id 
    and ix.index_id = ix.index_id 
    and ix.index_id > 1 
left join sys.columns c 
    on ic.object_id = c.object_id 
    and ic.column_id = c.column_id 
left join sys.columns cc 
    on ix.object_id = cc.object_id 
    and ix.index_id in (1,0) 
join sys.types t 
    on t.system_type_id = coalesce(c.system_type_id,cc.system_type_id) 
where o.type = 'U' 
order by object_name, index_name, column_name; 

然後,您可以識別出那些不安全聯機索引重建(BLOB/XML/CLR類型)。請注意,在SQL Server 2012中,取消了LOB列在線索引編制的限制,請參閱Online Index Operations for indexes containing LOB columns

+0

這正是我所期待的。謝謝! – stringpoet

0

我們最近做了這樣的程序。它爲此具有


ALTER PROCEDURE sp_rebuild_local_idexes 
@RebuildClustered bit = 0 
AS 
BEGIN 
    DECLARE @objectid int 
    DECLARE @indexid int 
    DECLARE @schemaname nvarchar(130) 
    DECLARE @objectname nvarchar(130) 
    DECLARE @indexname nvarchar(130) 
    DECLARE @partitions bigint 
    DECLARE @frag float 
    DECLARE @command nvarchar(4000) 
    DECLARE @HasBlobs bit 
    DECLARE @index_type_desc nvarchar(255) 

    -- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats function 
    -- and convert object and index IDs to names. 

    SELECT 
    --object_name(object_id), 
    object_id AS objectid, 
    index_id AS indexid, 
    avg_fragmentation_in_percent AS frag, 
    CASE WHEN (
     SELECT st.object_id 
      from sys.tables st 
      inner join sys.columns sc 
       on st.object_id=sc.object_id 
      inner join sys.types styp 
       on sc.system_type_id=styp.system_type_id and sc.max_length=styp.max_length 
      inner join sys.schemas ss 
       on st.schema_id=ss.schema_id 
      where styp.schema_id=4 
        and styp.name<>'sysname' 
        and styp.name IN ('xml','nvarchar','varchar','image','text','ntext') 
        AND st.object_id = a.object_id 
      group by st.object_id 
    ) IS NULL THEN 0 ELSE 1 END AS HasBlobs, 
    a.index_type_desc 
    INTO #work_to_do 
    FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED') AS a 
    WHERE avg_fragmentation_in_percent >= 5.0 AND index_id > 0 
       AND a.index_type_desc IN ('CLUSTERED INDEX','NONCLUSTERED INDEX')   
    ORDER BY a.index_type_desc 

    -- Declare the cursor for the list of partitions to be processed. 
    DECLARE partitions CURSOR FOR SELECT objectid, 
      indexid, 
      frag, 
      HasBlobs, 
      index_type_desc from #work_to_do 
select * from #work_to_do 
    -- Open the cursor. 
    OPEN partitions 

    -- Loop through the partitions. 
    WHILE (1=1) 
    BEGIN 
     FETCH NEXT FROM partitions 
     INTO @objectid, @indexid, @frag,@HasBlobs,@index_type_desc 

     IF @@FETCH_STATUS < 0 BREAK 

     IF @RebuildClustered = 1 AND @index_type_desc != 'CLUSTERED INDEX' 
      CONTINUE; 

     SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name) 
     FROM sys.objects AS o 
     JOIN sys.schemas as s ON s.schema_id = o.schema_id 
     WHERE o.object_id = @objectid 

     SELECT @indexname = QUOTENAME(name) 
     FROM sys.indexes 
     WHERE object_id = @objectid AND index_id = @indexid and type!=3 

     -- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding. 
     IF @frag < 30.0 
      SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE' 

     IF @frag >= 30.0 
     BEGIN 
      print @indexname+ @[email protected] 
      SET @command = N'ALTER INDEX ' + @indexname + 
          N' ON ' + 
          @schemaname + 
          N'.' + @objectname + 
          N' REBUILD' + 
          CASE WHEN @HasBlobs = 0 THEN ' WITH(ONLINE=ON)' ELSE '' END 
      print @command 
     END 

     EXEC (@command) 
     PRINT N'Executed: ' + @command 


    END 

    -- Close and deallocate the cursor. 
    CLOSE partitions 
    DEALLOCATE partitions 
END 

+0

這很有用,謝謝。 – stringpoet

相關問題