AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 167265
Accepted
Andrew Lackenby
Andrew Lackenby
Asked: 2017-03-16 07:40:53 +0800 CST2017-03-16 07:40:53 +0800 CST 2017-03-16 07:40:53 +0800 CST

编写压缩的非聚集索引的脚本

  • 772

没有人知道找到使用脚本压缩的非聚集索引的方法吗?我使用以下脚本编写它们,并希望更改它以添加压缩选项,现在我有企业可以玩了。

DECLARE @idxTableName SYSNAME
DECLARE @idxTableID INT
DECLARE @idxname SYSNAME
DECLARE @idxid INT
DECLARE @colCount INT
DECLARE @IxColumn SYSNAME
DECLARE @IxFirstColumn BIT
DECLARE @ColumnIDInTable INT
DECLARE @ColumnIDInIndex INT
DECLARE @IsIncludedColumn INT
DECLARE @sIncludeCols VARCHAR(4000)
DECLARE @sIndexCols VARCHAR(4000)
DECLARE @sSQL VARCHAR(4000)
DECLARE @rowcnt INT
DECLARE @sParamSQL VARCHAR(4000)
DECLARE @location SYSNAME
DECLARE @fillfactor INT

-- Get all the index info
DECLARE curidx CURSOR
FOR
SELECT object_name(si.object_id)
,si.object_id
,si.NAME
,si.index_id
FROM sys.indexes si
LEFT JOIN information_schema.table_constraints tc ON si.NAME = tc.constraint_name AND object_name(si.object_id) = tc.table_name
WHERE objectproperty(si.object_id, 'IsUserTable') = 1 AND [si].[type] = 2
ORDER BY object_name(si.object_id)
,si.index_id

OPEN curidx

FETCH NEXT
FROM curidx
INTO @idxTableName
,@idxTableID
,@idxname
,@idxid

--loop 
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @sSQL = 'IF NOT EXISTS (SELECT 1 FROM SYS.INDEXES WHERE name = ''' + @idxname + ''')' + CHAR(13)
SET @sSQL = @sSQL + 'BEGIN' + CHAR(13)
SET @sSQL = @sSQL + 'CREATE '

-- Check if the index is unique
IF (INDEXPROPERTY(@idxTableID, @idxname, 'IsUnique') = 1)
SET @sSQL = @sSQL + 'UNIQUE '

-- Check if the index is clustered
IF (INDEXPROPERTY(@idxTableID, @idxname, 'IsClustered') = 1)
SET @sSQL = @sSQL + 'CLUSTERED '
SET @sSQL = @sSQL + 'INDEX [' + @idxname + '] ON [' + @idxTableName + ']' + CHAR(13) + '('
SET @sSQL = @sSQL + CHAR(13)
SET @colCount = 0

SELECT @fillfactor = fill_factor
FROM sys.indexes 
WHERE name = @idxname

IF ISNULL(@fillfactor, 0) = 0
SET @fillfactor = 90

-- Get the number of cols in the index 
SELECT @colCount = COUNT(*)
FROM sys.index_columns ic
INNER JOIN sys.columns sc ON ic.object_id = sc.object_id AND ic.column_id = sc.column_id
WHERE ic.object_id = @idxtableid AND index_id = @idxid AND ic.is_included_column = 0

-- Get the file group info 
SELECT @location = f.[name]
FROM sys.indexes i
INNER JOIN sys.filegroups f ON i.data_space_id = f.data_space_id
INNER JOIN sys.all_objects o ON i.[object_id] = o.[object_id]
WHERE o.object_id = @idxTableID AND i.index_id = @idxid

-- Get all columns of the index
DECLARE curidxcolumn CURSOR
FOR
SELECT sc.column_id AS columnidintable
,sc.NAME
,ic.index_column_id columnidinindex
,ic.is_included_column AS isincludedcolumn
FROM sys.index_columns ic
INNER JOIN sys.columns sc ON ic.object_id = sc.object_id AND ic.column_id = sc.column_id
WHERE ic.object_id = @idxTableID AND index_id = @idxid
ORDER BY ic.index_column_id

SET @IxFirstColumn = 1
SET @sIncludeCols = ''
SET @sIndexCols = ''
SET @rowcnt = 0

OPEN curidxColumn

FETCH NEXT
FROM curidxColumn
INTO @ColumnIDInTable
,@IxColumn
,@ColumnIDInIndex
,@IsIncludedColumn

--loop 
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF @IsIncludedColumn = 0
BEGIN
SET @rowcnt = @rowcnt + 1
SET @sIndexCols = CHAR(9) + @sIndexCols + '[' + @IxColumn + ']'

-- Check the sort order of the index cols 
IF (INDEXKEY_PROPERTY(@idxTableID, @idxid, @ColumnIDInIndex, 'IsDescending')) = 0
SET @sIndexCols = @sIndexCols + ' ASC '
ELSE
SET @sIndexCols = @sIndexCols + ' DESC '

IF @rowcnt < @colCount
SET @sIndexCols = @sIndexCols + ', '
END
ELSE
BEGIN
-- Check for any include columns
IF len(@sIncludeCols) > 0
SET @sIncludeCols = @sIncludeCols + ','
SET @sIncludeCols = @sIncludeCols + '[' + @IxColumn + ']'

END

FETCH NEXT
FROM curidxColumn
INTO @ColumnIDInTable
,@IxColumn
,@ColumnIDInIndex
,@IsIncludedColumn
END

CLOSE curidxColumn

DEALLOCATE curidxColumn

--append to the result
IF LEN(@sIncludeCols) > 0
SET @sIndexCols = @sSQL + @sIndexCols + CHAR(13) + ') ' + ' INCLUDE ( ' + @sIncludeCols + ' ) '
ELSE
SET @sIndexCols = @sSQL + @sIndexCols + CHAR(13) + ') '

-- Build the options
SET @sParamSQL = ' WITH (FILLFACTOR = ' + cast(isnull(@fillfactor, 90) AS VARCHAR(3)) + ', '

--set @sParamSQL = ' WITH ('
IF (INDEXPROPERTY(@idxTableID, @idxname, 'IsPadIndex') = 1)
SET @sParamSQL = @sParamSQL + ' PAD_INDEX = ON, '
ELSE
SET @sParamSQL = @sParamSQL + ' PAD_INDEX = OFF, '

IF (INDEXPROPERTY(@idxTableID, @idxname, 'IsPageLockDisallowed') = 1)
SET @sParamSQL = @sParamSQL + ' ALLOW_PAGE_LOCKS = ON, '
ELSE
SET @sParamSQL = @sParamSQL + ' ALLOW_PAGE_LOCKS = OFF, '

IF (INDEXPROPERTY(@idxTableID, @idxname, 'IsRowLockDisallowed') = 1)
SET @sParamSQL = @sParamSQL + ' ALLOW_ROW_LOCKS = ON, '
ELSE
SET @sParamSQL = @sParamSQL + ' ALLOW_ROW_LOCKS = OFF, '

IF (INDEXPROPERTY(@idxTableID, @idxname, 'IsStatistics') = 1)
SET @sParamSQL = @sParamSQL + ' STATISTICS_NORECOMPUTE = ON, '
ELSE
SET @sParamSQL = @sParamSQL + ' STATISTICS_NORECOMPUTE = OFF, '

SET @sParamSQL = @sParamSQL + ' DROP_EXISTING = OFF ) '
SET @sIndexCols = @sIndexCols + CHAR(13) + @sParamSQL + ' ON [' + @location + ']' + CHAR(13) + 'END ' + CHAR(10) + 'GO' + CHAR(13)

PRINT @sIndexCols

FETCH NEXT
FROM curidx
INTO @idxTableName
,@idxTableID
,@idxname
,@idxid
END

CLOSE curidx
DEALLOCATE curidx
sql-server
  • 1 1 个回答
  • 250 Views

1 个回答

  • Voted
  1. Best Answer
    Hannah Vernon
    2017-03-16T12:00:02+08:002017-03-16T12:00:02+08:00

    我使用此脚本获取有关索引的详细信息,包括非聚集索引。它提供了很好的细节,我们用它来重组/重建索引。

    SELECT ObjectName = QUOTENAME(s.name) + '.' + QUOTENAME(o.name)
        , IndexName = QUOTENAME(i.name)
        , PadIndex = CASE WHEN i.is_padded = 1 THEN 'PAD_INDEX = ON' ELSE 'PAD_INDEX = OFF' END
        , [FillFactor] = 'FILLFACTOR = ' + CONVERT(VARCHAR(50), CASE WHEN i.fill_factor = 0 THEN 100 ELSE i.fill_factor END)
        , [AllowPageLocks] = 'ALLOW_PAGE_LOCKS = ' + CASE WHEN i.allow_page_locks = 1 THEN 'ON' ELSE 'OFF' END
        , [AllowRowLocks] = 'ALLOW_ROW_LOCKS = ' + CASE WHEN i.allow_row_locks = 1 THEN 'ON' ELSE 'OFF' END
        , [DataSpace] = 'ON ' + ds.name
        , IgnoreDupeKey = 'IGNORE_DUP_KEY = ' + CASE WHEN i.ignore_dup_key = 1 THEN 'ON' ELSE 'OFF' END
        , CompressOption = 'DATA_COMPRESSION = ' + p.data_compression_desc
        , PartitionNumber = p.partition_number
        , NumberOfFragments = ips.fragment_count
        , NumberOfPages = ips.page_count
        , AvgFragmentSizeInPages = ips.avg_fragment_size_in_pages
        , AvgFragmentationInPercent = ips.avg_fragmentation_in_percent
        , IndexType = i.type_desc
        , IsUnique = i.is_unique
        , IsPrimary = i.is_primary_key
        , IsPartitioned = CASE WHEN ps.data_space_id IS NULL THEN 0 ELSE 1 END
        , IsClustered = CASE WHEN i.type = 1 THEN 1 ELSE 0 END
    FROM sys.indexes i
        INNER JOIN sys.objects o ON i.object_id = o.object_id
        INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
        INNER JOIN sys.data_spaces ds ON i.data_space_id = ds.data_space_id
        INNER JOIN sys.partitions p ON o.object_id = p.object_id
                                        AND i.index_id = p.index_id
        LEFT JOIN sys.partition_schemes ps ON ds.data_space_id = ps.data_space_id
    CROSS APPLY sys.dm_db_index_physical_stats(DB_ID(), o.object_id, i.index_id, p.partition_number, 'SAMPLED') ips
    WHERE o.is_ms_shipped = 0
        AND NOT (
            o.type = 'TF' -- table valued function
            OR o.type = 'TT' -- table type
            OR o.type = 'SO' -- sequence object
            )
        AND i.index_id > 0
        AND i.is_disabled = 0
        AND i.is_hypothetical = 0
        AND (
            ds.type = 'FG' -- filegroup
            OR ds.type = 'PS' -- partition stream
            ) 
        AND i.type_desc IN 
            ( 
                'CLUSTERED'
                , 'NONCLUSTERED'
                , 'XML'
            )
    ORDER BY QUOTENAME(s.name) + '.' + QUOTENAME(o.name)
        , QUOTENAME(i.name);
    

    返回的详细信息如下所示:

    +----------------+---------------------------- ----+----------------+----------------+-------- --------------+--------------------+---------- ------+--------------------+---------------- ------+----------------+----------------+---- ----------+------------------------+------------ --------------+------------+----------+----------+ --------------+------------+
    | 对象名称 | 索引名称 | 填充索引 | 填充因子 | 允许页面锁定 | 允许行锁 | 数据空间 | 忽略重复键 | 压缩选项 | 分区号 | 片段数 | 页数 | AvgFragmentSizeInPages | AvgFragmentationInPercent | 索引类型 | 是独一无二的 | 是主要的 | 已分区 | 集群 |
    +----------------+---------------------------- ----+----------------+----------------+-------- --------------+--------------------+---------- ------+--------------------+---------------- ------+----------------+----------------+---- ----------+------------------------+------------ --------------+------------+----------+----------+ --------------+------------+
    | [dbo].[部分测试] | [PK__PartTest__3214EC275AC4DD06] | PAD_INDEX = 关闭 | 填充因子 = 100 | ALLOW_PAGE_LOCKS = 开 | ALLOW_ROW_LOCKS = 开 | ON PartSchemeTest | IGNORE_DUP_KEY = 关闭 | 数据压缩 = 无 | 1 | 0 | 0 | 0 | 0 | 集群 | 1 | 1 | 1 | 1 |
    | [dbo].[部分测试] | [PK__PartTest__3214EC275AC4DD06] | PAD_INDEX = 关闭 | 填充因子 = 100 | ALLOW_PAGE_LOCKS = 开 | ALLOW_ROW_LOCKS = 开 | ON PartSchemeTest | IGNORE_DUP_KEY = 关闭 | 数据压缩 = 无 | 2 | 14 | 100 | 7.14285714285714 | 2 | 集群 | 1 | 1 | 1 | 1 |
    | [dbo].[部分测试] | [PK__PartTest__3214EC275AC4DD06] | PAD_INDEX = 关闭 | 填充因子 = 100 | ALLOW_PAGE_LOCKS = 开 | ALLOW_ROW_LOCKS = 开 | ON PartSchemeTest | IGNORE_DUP_KEY = 关闭 | 数据压缩 = 无 | 3 | 15 | 100 | 6.66666666666667 | 3 | 集群 | 1 | 1 | 1 | 1 |
    | [dbo].[部分测试] | [PK__PartTest__3214EC275AC4DD06] | PAD_INDEX = 关闭 | 填充因子 = 100 | ALLOW_PAGE_LOCKS = 开 | ALLOW_ROW_LOCKS = 开 | ON PartSchemeTest | IGNORE_DUP_KEY = 关闭 | 数据压缩 = 无 | 5 | 1909 年 | 14880 | 7.79465688842326 | 0.376344086021505 | 集群 | 1 | 1 | 1 | 1 |
    | [dbo].[部分测试] | [PK__PartTest__3214EC275AC4DD06] | PAD_INDEX = 关闭 | 填充因子 = 100 | ALLOW_PAGE_LOCKS = 开 | ALLOW_ROW_LOCKS = 开 | ON PartSchemeTest | IGNORE_DUP_KEY = 关闭 | DATA_COMPRESSION = 页 | 4 | 6 | 50 | 8.33333333333333 | 4 | 集群 | 1 | 1 | 1 | 1 |
    +----------------+---------------------------- ----+----------------+----------------+-------- --------------+--------------------+---------- ------+--------------------+---------------- ------+----------------+----------------+---- ----------+------------------------+------------ --------------+------------+----------+----------+ --------------+------------+
    • 1

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve