我正在尝试在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,我已将其排除在外。
以下是错误抱怨的表和索引的定义:
我的SQL语句错过了哪些内容?