Existe-t-il un moyen fiable de déterminer quand vous devez exécuter DBCC CLEANTABLE pour récupérer de l'espace?

11

Dernièrement, au lieu de simplement augmenter les fichiers lorsqu'ils approchent de 80% d'utilisation des fichiers, j'ai été plus proactif pour récupérer de l'espace via les astuces habituelles comme la défragmentation des tas, l'ajout et la suppression d'index clusterisés, l'implémentation de la compression de lignes ou de pages, etc.

Cependant, il y a quelques cas où j'ai pu récupérer encore plus d'espace en exécutant DBCC CLEANTABLE . Avec des centaines de bases de données dans mon environnement, il n'est pas possible de savoir ce que les utilisateurs font dans chacun et il est tout à fait acceptable qu'il y ait des changements impliquant la suppression de colonnes de longueur fixe. J'ai généralement trouvé ces opportunités en examinant le nombre de lignes par rapport au nombre de pages dans certains scripts d'utilisation de l'espace objet que j'ai écrits. J'aimerais aller un peu plus loin en essayant d'automatiser la détection de ce type de scénarios.

Ce que j'aimerais savoir, c'est si quelqu'un là-bas surveille activement ce genre d'opportunités et si oui, que recherchez-vous en particulier?

Mes pensées étaient d'écrire quelque chose dans le sens de rassembler la taille maximale et minimale d'une ligne, le nombre de lignes dans le tableau, le nombre de pages allouées et le nombre de pages utilisées, puis de faire quelques calculs de base pour enregistrer les résultats qui sont bien en dehors de ce qui serait "attendu".

AndrewSQL
la source
Je recommande fortement d'utiliser le paramètre batch_size sur les grandes tables. Cela entraînera l'exécution de la commande dans une série de transactions, par opposition à une transaction géante.
datagod

Réponses:

11

La solution à laquelle je penserais pour ce problème est d'exécuter chaque semaine un travail qui exécutera sp_spaceused pour toutes les tables d'une base de données et enregistrera ces données dans une table. S'il y a des différences de taille pour chaque table supérieures à ... disons 10%, je lancerais la table de nettoyage dbcc.

Mon code pour parcourir les tailles de table ressemble à ça:

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;

Il ne vous reste plus qu'à créer la logique qui vérifiera quel serait le changement de taille au cours de la semaine et le planifiera.

Marian
la source
Maintenant, s'il y a des raisons de soupçonner des inexactitudes dans les rapports de taille de table, vous devriez opter pour DBCC UPDATEUSAGE (cela corrigera le nombre de lignes et de pages). Heureux d'avoir pu aider!
Marian