J'ai une base de données que j'ai essayé de défragmenter toutes les tables à la fois en exécutant ce T-SQL:
SELECT
'ALTER INDEX all ON ' + name + ' REORGANIZE;' + CHAR(10) +
'ALTER INDEX all ON ' + name + ' REBUILD;'
FROM sys.tables
Et puis copier et coller la sortie dans une nouvelle fenêtre de requête et l'exécuter. Je n'ai eu aucune erreur, mais j'ai encore une fragmentation. J'ai également essayé d'exécuter les deux commandes séparément et j'ai toujours une fragmentation. Note: J'ai été informé que REORGANIZE
n'est pas nécessaire par Aaron, et je suis conscient que je pourrais utiliser SQL dynamique pour automatiser cela.
J'ai exécuté ceci pour déterminer que j'ai toujours une fragmentation:
SELECT * FROM
sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, NULL)
WHERE avg_fragmentation_in_percent > 0
Et j'ai eu:
database_id object_id index_id partition_number index_type_desc alloc_unit_type_desc index_depth index_level avg_fragmentation_in_percent fragment_count avg_fragment_size_in_pages page_count avg_page_space_used_in_percent record_count ghost_record_count version_ghost_record_count min_record_size_in_bytes max_record_size_in_bytes avg_record_size_in_bytes forwarded_record_count compressed_page_count
85 171147655 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 36.3636363636364 5 2.2 11 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 421576540 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 75 7 1.14285714285714 8 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 965578478 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 14.7058823529412 6 5.66666666666667 34 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1061578820 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 40 4 1.25 5 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1109578991 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 30.7692307692308 5 2.6 13 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1205579333 2 1 NONCLUSTERED INDEX IN_ROW_DATA 2 0 50 5 1.6 8 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1493580359 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 50 6 1.66666666666667 10 NULL NULL NULL NULL NULL NULL NULL NULL NULL
Je sais que je manque quelque chose de vraiment basique, mais je ne sais pas quoi.
Les tables sont minuscules. Le nombre de pages dans vos tableaux est le suivant:
11, 8, 6, 5, 13, 8, 10
Ils occupent 480 Ko au total. Il n'y a littéralement rien à défragmenter.
Edit: Cela mérite un peu plus d'explications.
Une nouvelle table ou un nouvel index est généralement alloué sur les 8 premières pages d'une étendue mixte plutôt que uniforme. Ainsi, il est possible que chacune des 8 premières pages soit allouée à partir d'étendues mixtes différentes. Une table ou un index consommant 8 pages pourrait donc avoir 8 fragments, 1 sur chacune des 8 extensions mixtes différentes.
Les scripts de défragmentation les plus largement utilisés (quelques exemples liés ci-dessous) ont tendance à exclure les petites tables à cause de cela. IIRC, <500 pages est dans l'un ou les deux. À ces tailles, la défragmentation présente très peu d'avantages et les chiffres de fragmentation sont potentiellement faussés par les allocations d'étendues mixtes.
Citation de " Meilleures pratiques de défragmentation d'index Microsoft SQL Server 20 ":
"La fragmentation affecte les E/S du disque. Par conséquent, concentrez-vous sur les index plus volumineux car leurs pages sont moins susceptibles d'être mises en cache par SQL Server. Utilisez le nombre de pages signalé par DBCC SHOWCONTIG pour avoir une idée de la taille des index (chaque page est 8 Ko.) En règle générale, vous ne devez pas vous préoccuper des niveaux de fragmentation des index de moins de 1 000 pages. Dans les tests, les index contenant plus de 10 000 pages ont réalisé des gains de performances, les plus importants gains sur les index avec beaucoup plus de pages (plus de 50 000 pages) . "
Donc, ce genre de réponses à votre question et soutient les réponses de Mark et Aaron.
Vous pouvez trouver de bonnes informations sur la fragmentation d'index dans les articles suivants de Brent Ozar:
Aussi ... un océan d'informations intéressantes sur les index en général (également sur les problèmes de fragmentation) peut être trouvé sur le blog de Kimberly Tripp .
Ce n'est pas censé répondre à votre question, mais cela ne rentrera jamais dans un commentaire. Vous pouvez créer ce script dynamiquement sans avoir à copier et coller la sortie dans une autre fenêtre. Tenant compte du fait qu'il n'y a absolument aucune raison de REORGANIZE
puis REBUILD
:
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'ALTER INDEX all ON ' + name + ' REBUILD;
' FROM sys.tables;
PRINT @sql; -- to see the first 8,000 characters and make sure it checks out
-- EXEC sp_executesql @sql;