Comment pourrais-je rechercher les plus gros objets d'une base de données SQL Server? Tout d'abord, en déterminant quelles tables (et les index associés) sont les plus grandes, puis quelles lignes d'une table sont les plus grandes (nous stockons des données binaires dans des BLOB)?
Existe-t-il des outils pour vous aider dans ce type d'analyse de base de données? Ou y a-t-il des requêtes simples que je pourrais exécuter sur les tables système?
J'utilise ce script SQL (que j'ai reçu de quelqu'un, quelque part - je ne peux pas reconstruire d'où il vient) - cela m'a beaucoup aidé à comprendre et à déterminer la taille des index et des tables:
SELECT
t.name AS TableName,
i.name as indexName,
sum(p.rows) as RowCounts,
sum(a.total_pages) as TotalPages,
sum(a.used_pages) as UsedPages,
sum(a.data_pages) as DataPages,
(sum(a.total_pages) * 8) / 1024 as TotalSpaceMB,
(sum(a.used_pages) * 8) / 1024 as UsedSpaceMB,
(sum(a.data_pages) * 8) / 1024 as DataSpaceMB
FROM
sys.tables t
INNER JOIN
sys.indexes i ON t.object_id = i.object_id
INNER JOIN
sys.partitions p ON i.object_id = p.object_id AND i.index_id = p.index_id
INNER JOIN
sys.allocation_units a ON p.partition_id = a.container_id
WHERE
t.name NOT LIKE 'dt%' AND
i.object_id > 255 AND
i.index_id <= 1
GROUP BY
t.name, i.object_id, i.index_id, i.name
ORDER BY
object_name(i.object_id)
Bien sûr, vous pouvez utiliser un autre critère de classement, par exemple.
ORDER BY SUM(p.rows) DESC
pour obtenir les tables avec le plus de lignes, ou
ORDER BY SUM(a.total_pages) DESC
pour obtenir les tables avec le plus de pages (blocs de 8K) utilisées.
Dans SQL Server 2008, vous pouvez également simplement exécuter le rapport standard Utilisation du disque par tables principales. Ceci peut être trouvé en clic droit la base de données, en sélectionnant Rapports-> Rapports standard et en sélectionnant le rapport souhaité.
Vous pouvez également utiliser le code suivant:
USE AdventureWork
GO
CREATE TABLE #GetLargest
(
table_name sysname ,
row_count INT,
reserved_size VARCHAR(50),
data_size VARCHAR(50),
index_size VARCHAR(50),
unused_size VARCHAR(50)
)
SET NOCOUNT ON
INSERT #GetLargest
EXEC sp_msforeachtable 'sp_spaceused ''?'''
SELECT
a.table_name,
a.row_count,
COUNT(*) AS col_count,
a.data_size
FROM #GetLargest 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 #GetLargest
Cette aide à la recherche pour trouver la plus grande table dans vous êtes la connexion.
SELECT TOP 1 OBJECT_NAME(OBJECT_ID) TableName, st.row_count
FROM sys.dm_db_partition_stats st
WHERE index_id < 2
ORDER BY st.row_count DESC
J'ai trouvé cette requête également très utile dans SqlServerCentral, voici le lien vers le message d'origine
plus grandes tables SQL Server
select name=object_schema_name(object_id) + '.' + object_name(object_id)
, rows=sum(case when index_id < 2 then row_count else 0 end)
, reserved_kb=8*sum(reserved_page_count)
, data_kb=8*sum( case
when index_id<2 then in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count
else lob_used_page_count + row_overflow_used_page_count
end )
, index_kb=8*(sum(used_page_count)
- sum( case
when index_id<2 then in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count
else lob_used_page_count + row_overflow_used_page_count
end )
)
, unused_kb=8*sum(reserved_page_count-used_page_count)
from sys.dm_db_partition_stats
where object_id > 1024
group by object_id
order by
rows desc
Dans ma base de données, ils ont donné des résultats différents entre cette requête et la première réponse.
J'espère que quelqu'un trouve utile
Si vous utilisez SQL Server Management Studio 2008, vous pouvez afficher certains champs de données dans la fenêtre de détails de l'explorateur d'objets. Il suffit de parcourir et de sélectionner le dossier des tables. Dans la vue Détails, vous pouvez cliquer avec le bouton droit de la souris sur les titres des colonnes et ajouter des champs au "rapport". Votre kilométrage peut varier si vous utilisez SSMS 2008 Express.
La réponse de @ marc_s est très bonne et je l'utilise depuis quelques années. Cependant, j'ai remarqué que le script manque des données dans certains index columnstore et ne montre pas une image complète. Par exemple. lorsque vous utilisez SUM(TotalSpace)
contre le script et que vous le comparez à la propriété de base de données d'espace total dans Management Studio, les numéros ne correspondent pas dans mon cas (Management Studio affiche des nombres plus grands). J'ai modifié le script pour surmonter ce problème et je l'ai étendu un peu:
select
tables.[name] as table_name,
schemas.[name] as schema_name,
isnull(db_name(dm_db_index_usage_stats.database_id), 'Unknown') as database_name,
sum(allocation_units.total_pages) * 8 as total_space_kb,
cast(round(((sum(allocation_units.total_pages) * 8) / 1024.00), 2) as numeric(36, 2)) as total_space_mb,
sum(allocation_units.used_pages) * 8 as used_space_kb,
cast(round(((sum(allocation_units.used_pages) * 8) / 1024.00), 2) as numeric(36, 2)) as used_space_mb,
(sum(allocation_units.total_pages) - sum(allocation_units.used_pages)) * 8 as unused_space_kb,
cast(round(((sum(allocation_units.total_pages) - sum(allocation_units.used_pages)) * 8) / 1024.00, 2) as numeric(36, 2)) as unused_space_mb,
count(distinct indexes.index_id) as indexes_count,
max(dm_db_partition_stats.row_count) as row_count,
iif(max(isnull(user_seeks, 0)) = 0 and max(isnull(user_scans, 0)) = 0 and max(isnull(user_lookups, 0)) = 0, 1, 0) as no_reads,
iif(max(isnull(user_updates, 0)) = 0, 1, 0) as no_writes,
max(isnull(user_seeks, 0)) as user_seeks,
max(isnull(user_scans, 0)) as user_scans,
max(isnull(user_lookups, 0)) as user_lookups,
max(isnull(user_updates, 0)) as user_updates,
max(last_user_seek) as last_user_seek,
max(last_user_scan) as last_user_scan,
max(last_user_lookup) as last_user_lookup,
max(last_user_update) as last_user_update,
max(tables.create_date) as create_date,
max(tables.modify_date) as modify_date
from
sys.tables
left join sys.schemas on schemas.schema_id = tables.schema_id
left join sys.indexes on tables.object_id = indexes.object_id
left join sys.partitions on indexes.object_id = partitions.object_id and indexes.index_id = partitions.index_id
left join sys.allocation_units on partitions.partition_id = allocation_units.container_id
left join sys.dm_db_index_usage_stats on tables.object_id = dm_db_index_usage_stats.object_id and indexes.index_id = dm_db_index_usage_stats.index_id
left join sys.dm_db_partition_stats on tables.object_id = dm_db_partition_stats.object_id and indexes.index_id = dm_db_partition_stats.index_id
group by schemas.[name], tables.[name], isnull(db_name(dm_db_index_usage_stats.database_id), 'Unknown')
order by 5 desc
J'espère que ce sera utile pour quelqu'un. Ce script a été testé sur de grandes bases de données à l’échelle de la tuberculose contenant des centaines de tables, d’index et de schémas différents.