21

有没有人碰巧有一个通用的 SQL 语句,它会列出每个分区的数据库中的所有表和索引,以及它们当前的压缩设置?

谢谢。

编辑:这是我尝试查询表时的结果,但我不确定连接是否正确(我得到了重复,这似乎是由索引的存在引起的)

SELECT [t].[name], [p].[partition_number], [p].[data_compression_desc]
FROM [sys].[partitions] AS [p]
INNER JOIN sys.tables AS [t] ON [t].[object_id] = [p].[object_id]
4

4 回答 4

40

我想我会分享我的最终查询。这将给出两个结果集,第一个是堆和聚集索引的数据压缩,第二个是非聚集索引的索引压缩。

SELECT [t].[name] AS [Table], [p].[partition_number] AS [Partition],
    [p].[data_compression_desc] AS [Compression]
FROM [sys].[partitions] AS [p]
INNER JOIN sys.tables AS [t] ON [t].[object_id] = [p].[object_id]
WHERE [p].[index_id] in (0,1)

SELECT [t].[name] AS [Table], [i].[name] AS [Index],  
    [p].[partition_number] AS [Partition],
    [p].[data_compression_desc] AS [Compression]
FROM [sys].[partitions] AS [p]
INNER JOIN sys.tables AS [t] ON [t].[object_id] = [p].[object_id]
INNER JOIN sys.indexes AS [i] ON [i].[object_id] = [p].[object_id] AND [i].[index_id] = [p].[index_id]
WHERE [p].[index_id] > 1
于 2013-06-10T09:08:10.553 回答
12

虽然我认为虽然 Barguast 发布的最终查询可能有效,但它们仍然存在问题/解释得不够好。

基本上0index_id1聚集索引2是其他所有索引(非聚集索引)。

上述查询的问题是,如果表是堆(即使表中有数据),对数据的查询将不起作用。此外,索引查询也有效,因为您指定了index_Id = 2and 由于没有加入index_idbetweensys.indexes和而存在欺骗sys.partitions。如果你加入这些,那么结果集中就不会出现重复,你可以做的更容易理解index_id not in (0,1)

无论如何,固定查询如下。我还在第一个查询中添加了索引名称(请注意,如果表是堆,则此字段将为空)。另请注意,您不必index_id在第一个查询中指定连接,因为where指定(0,1)并且只能是其中一个(换句话说,如果您愿意,您可以添加它,但它没有任何区别)。

-- Data (table) compression (heap or clustered index)
SELECT [t].[name] AS [Table], 
       [i].[name] AS [Index],
       [p].[partition_number] AS [Partition],
       [p].[data_compression_desc] AS [Compression]
FROM [sys].[partitions] AS [p]
INNER JOIN sys.tables AS [t] 
     ON [t].[object_id] = [p].[object_id]
INNER JOIN sys.indexes AS [i] 
     ON [i].[object_id] = [p].[object_id]
WHERE [p].[index_id] in (0,1)

-- Index compression (non-clustered index)
SELECT [t].[name] AS [Table], 
       [i].[name] AS [Index],  
       [p].[partition_number] AS [Partition],
       [p].[data_compression_desc] AS [Compression]
FROM [sys].[partitions] AS [p]
INNER JOIN sys.tables AS [t] 
     ON [t].[object_id] = [p].[object_id]
INNER JOIN sys.indexes AS [i] 
     ON [i].[object_id] = [p].[object_id] AND i.index_id = p.index_id
WHERE [p].[index_id] not in (0,1)
于 2014-01-21T15:36:19.827 回答
11

这些答案都是体面且有效的。因为我为我的工作做了一些修饰,所以我认为是时候回馈一下了。此查询添加来自 Jason 的答案(我需要)的模式。它还整理了一些连接问题并将结果组合成一个非常简单的摘要。

-- Returns user tables and indexes in a DB and their Compression state
select s.name [Schema], t.name [Table], i.name [Index], p.data_compression_desc Compression
     , case when p.index_id in (0, 1) then 'Table' else 'Index' end CompressionObject
  from sys.tables t
  join sys.schemas s on t.schema_id = s.schema_id
  join sys.indexes i on t.object_id = i.object_id
  join sys.partitions p on (i.object_id = p.object_id and i.index_id = p.index_id)
where t.type = 'U'
order by 1, 2, p.index_id, 3

我将其用作“工作列表”来生成脚本以压缩所有内容,因为我只是将数据库提升到 Azure VM 并希望降低 IOPS 以提高性能。希望这可以帮助那里的人。

于 2014-08-02T17:36:46.040 回答
4

这应该可以完成工作,对其进行一小部分测试,以确保它可以满足您的需求

SELECT DISTINCT s.name [Schema], t.name [Table], i.name [Index Name], p.partition_number, p.data_compression_desc
-- uncommenting the below line will give you dupes
--, p.index_id
FROM sys.schemas s
INNER JOIN sys.tables t
    ON s.schema_id = t.schema_id
    INNER JOIN sys.indexes i
        ON t.object_id = i.object_id
    INNER JOIN sys.partitions p
        ON t.object_id = p.object_id
ORDER BY s.name, t.name

您可能被骗的原因是因为每个表有多个分区记录,例如多个 index_id,请参阅此MSDN文章以了解 index_id 的含义。添加DISTINCT应​​该可以解决欺骗的问题

于 2013-06-07T22:22:24.413 回答