无法对索引

时间:2017-04-07 18:44:17

标签: sql-server database-indexes

我正在尝试在SQL SERVER 2014企业数据库服务器上重新构建/重新构建索引。我在网上的帮助下编写了以下存储过程:

USE [ManagementReporter]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[REORGANIZE_TOP_INDEXES_NO_PAGE]
AS
    DECLARE @dbname            SYSNAME = DB_NAME(),
            @schema_name       SYSNAME,
            @page_count        INT,
            @table_name        SYSNAME,
            @index_name        SYSNAME,
            @avg_fragmentation FLOAT,
            @sql               NVARCHAR(MAX)

    -- Do re-indexing
    DECLARE INDEXFRAGMENTATION CURSOR FAST_FORWARD FOR
      SELECT DISTINCT TOP 5000 DBSCHEMAS.[NAME] AS 'Schema',
                      DBTABLES.[NAME] AS 'Table',
                      DBINDEXES.[NAME] AS 'Index',
                      INDEXSTATS.AVG_FRAGMENTATION_IN_PERCENT AS 'Frag %',
                      PAGE_COUNT
        FROM SYS.DM_DB_INDEX_PHYSICAL_STATS (DB_ID(), NULL, NULL, NULL, NULL) AS INDEXSTATS
             INNER JOIN SYS.TABLES dbtables
                     ON DBTABLES.[OBJECT_ID] = INDEXSTATS.[OBJECT_ID]
             INNER JOIN SYS.SCHEMAS dbschemas
                     ON DBTABLES.[SCHEMA_ID] = DBSCHEMAS.[SCHEMA_ID]
             INNER JOIN SYS.INDEXES AS DBINDEXES
                     ON DBINDEXES.[OBJECT_ID] = INDEXSTATS.[OBJECT_ID]
                    AND INDEXSTATS.INDEX_ID = DBINDEXES.INDEX_ID
             INNER JOIN SYS.INDEX_COLUMNS AS DBINDEXCOLUMNS
                     ON DBINDEXCOLUMNS.[OBJECT_ID] = DBINDEXES.[OBJECT_ID]
             INNER JOIN SYS.COLUMNS AS DBSYSCOLUMNS
                     ON DBSYSCOLUMNS.[OBJECT_ID] = DBINDEXCOLUMNS.[OBJECT_ID]
                    AND DBSYSCOLUMNS.COLUMN_ID = DBINDEXCOLUMNS.COLUMN_ID
       WHERE INDEXSTATS.DATABASE_ID = DB_ID()
         AND DBINDEXES.NAME IS NOT NULL
         AND NOT ( DBSYSCOLUMNS.SYSTEM_TYPE_ID IN ( 34, 35, 99, 173, 241 ) --IMAGE, TEXT, NTEXT, BINARY, XML
                    OR ( DBSYSCOLUMNS.SYSTEM_TYPE_ID IN ( 165, 167, 231 )  --VARBINARY, VARCHAR, NVARCHAR
                         AND DBSYSCOLUMNS.MAX_LENGTH = -1 ) )
       ORDER BY INDEXSTATS.AVG_FRAGMENTATION_IN_PERCENT DESC  

    OPEN INDEXFRAGMENTATION
    FETCH NEXT FROM INDEXFRAGMENTATION INTO @schema_name,
                                            @table_name,
                                            @index_name,
                                            @avg_fragmentation,
                                            @page_count

    WHILE @@FETCH_STATUS = 0
      BEGIN
        IF @avg_fragmentation > 20 -- ReBuild index          
          SET @sql = 'ALTER INDEX [' + @index_name + '] ON [' + @schema_name + '].[' + @table_name + '] REBUILD WITH (ONLINE = ON (WAIT_AT_LOW_PRIORITY (MAX_DURATION= 20, ABORT_AFTER_WAIT=BLOCKERS)))';
        ELSE -- ReOrganize index       
          SET @sql = 'ALTER INDEX [' + @index_name + '] ON [' + @schema_name + '].[' + @table_name + '] REORGANIZE;';

        EXEC (@sql)        

        FETCH NEXT FROM INDEXFRAGMENTATION INTO @schema_name,
                                                @table_name,
                                                @index_name,
                                                @avg_fragmentation,
                                                @page_count
      END

    CLOSE INDEXFRAGMENTATION
    DEALLOCATE INDEXFRAGMENTATION

从我在WEB上看到的内容,我想如果我忽略了上述SYSTEM_TYPE_ID的索引,我认为它不会将这些索引带回我的结果集中。但是,以下索引仍然被选中并产生以下错误:

  

Msg 2725,Level 16,State 2,Line 3在线操作不能   为索引'PK_ReportOutput'执行,因为索引包含   列'EmailMessage'的数据类型为text,ntext,image或FILESTREAM。   对于非聚集索引,该列可以是包含列   指数。对于聚簇索引,该列可以是任何列   桌子。如果使用DROP_EXISTING,则列可以是新列的一部分   或旧索引。该操作必须离线执行。

EmailMessage列定义为(ntext,not null),所以我不明白为什么用上面的主SQL选择它?看起来ntext的system_type_id为99,我已将其排除在外。

以下是错误抱怨的表和索引的定义:

enter image description here

我的SQL语句错过了哪些内容?

0 个答案:

没有答案