Есть ли надежный способ определить, когда вы должны запустить DBCC CLEANTABLE, чтобы освободить место?

11

В последнее время, вместо того, чтобы просто увеличивать файлы, когда их использование почти достигает 80%, я стал более активно восстанавливать пространство с помощью обычных приемов, таких как дефрагментация кучи, добавление и удаление кластеризованных индексов, реализация сжатия строк или страниц и т. Д.

Однако есть несколько случаев, когда мне удалось освободить еще больше места, выполнив DBCC CLEANTABLE . С сотнями баз данных в моей среде невозможно узнать, что пользователи делают в каждой из них, и вполне приемлемо, что будут изменения, включающие удаление столбцов фиксированной длины. Обычно я обнаруживал эти возможности, глядя на количество строк и количество страниц в некоторых написанных мной сценариях использования пространства объектов. Я хотел бы сделать еще один шаг, пытаясь автоматизировать обнаружение подобных сценариев.

Что я хотел бы знать, так это то, что кто-то там активно отслеживает подобные возможности, и если да, то на что конкретно вы обращаете внимание?

Мои мысли заключались в том, чтобы написать что-то вроде сбора максимального и минимального размера строки, количества строк в таблице, количества выделенных страниц и количества используемых страниц, а затем выполнить некоторые основные математические операции для регистрации результатов, которые находятся далеко за пределами того, что было бы "ожидаемым".

AndrewSQL
источник
Я настоятельно рекомендую использовать параметр batch_size для больших таблиц. Это приведет к выполнению команды в серии транзакций, а не в одной гигантской транзакции.
датагод

Ответы:

11

Решение этой проблемы, о котором я думаю, заключается в том, чтобы еженедельно запускать задание, которое будет запускать sp_spaceused для всех таблиц в базе данных, и сохранять эти данные в таблице. Если есть различия в размере для каждой таблицы больше, чем, скажем, на 10%, я бы запустил команду dbcc cleantable.

Мой код для циклического перебора размеров таблицы выглядит так:

if OBJECT_ID ('tempdb.dbo.#temp') is not null
    drop table #temp;

if OBJECT_ID ('dbo.BigTables') is not null
    drop table dbo.BigTables;
go

CREATE TABLE [dbo].[BigTables] (
    [table_name] [sysname] NOT NULL,
    [row_count] [int] NULL,
    [col_count] [int] NULL,
    [data_size] [varchar](50) NULL,
    [Date] [datetime] NOT NULL,
    [DBName] [nvarchar](128) NULL
);
GO

CREATE TABLE #temp (
    table_name sysname ,
    row_count int,
    reserved_size varchar(50),
    data_size varchar(50),
    index_size varchar(50),
    unused_size varchar(50)
);
go

INSERT     #temp
EXEC       sp_msforeachtable 'sp_spaceused ''?'''

insert into dbo.BigTables
SELECT     a.table_name,
           a.row_count,
           count(*) as col_count,
           a.data_size,
           getdate() as [Date],
    'MY DB' as DBName
FROM       #temp a
INNER JOIN information_schema.columns b
           ON a.table_name collate database_default
                = b.table_name collate database_default
GROUP BY   a.table_name, a.row_count, a.data_size
ORDER BY   CAST(Replace(a.data_size, ' KB', '') as integer) desc

DROP TABLE #temp;

Select * from dbo.BigTables;

Теперь вам нужно только построить логику, которая будет проверять, как будет изменяться размер в течение недели, и планировать ее.

Мэриан
источник
Теперь, если есть причины подозревать неточности в отчетах о размерах таблиц, вам следует использовать DBCC UPDATEUSAGE (это исправит количество строк и страниц). Рад помочь!
Marian