Can SQL Server system tables be defragmented?

Are you sure you have positively and accurately identified this system table as the sole source of "unnecessary pressure on the buffer pool and also negatively impacts the performance of operations such as computing the size of all tables in a database"? Are you sure this system table isn't self-managed in such a way that (a) fragmentation is minimized or kept in check secretly or just (b) managed efficiently in memory so that defragmentation levels really don't affect anything much?

You can see how many pages are in use, and you can see how much free space is on the pages that are in memory (page_free_space_percent is always NULL in the allocations DMF, but this is available from the buffer DMV) - this should give you some idea if what you're worrying about is really something you should be worrying about:

SELECT 
  Number_of_Pages = COUNT(*), 
  Number_of_Pages_In_Memory = COUNT(b.page_id),
  Avg_Free_Space = AVG(b.free_space_in_bytes/8192.0) 
FROM sys.dm_db_database_page_allocations
(
  DB_ID(),
  OBJECT_ID(N'sys.syscolpars'),
  NULL,NULL,'DETAILED'
) AS p
LEFT OUTER JOIN sys.dm_os_buffer_descriptors AS b
ON b.database_id = DB_ID() 
AND b.page_id = p.allocated_page_page_id 
AND b.file_id = p.allocated_page_file_id;

If your number of pages is small (like probably < 10000 for system tables) or if the free space is "low" (not sure what your typical thresholds are for reorg/rebuild), focus on other, more interesting, low-hanging fruit.

If your number of pages is large and the free space is "high", ok, then maybe I'm giving SQL Server too much credit for its own self-maintenance. As you showed from the other question, this works...

ALTER INDEX ALL ON sys.syscolpars REORGANIZE;

...and does reduce fragmentation. Though it may require elevated permissions (I did not try as a peon).

Maybe you can just do this periodically as part of your own maintenance, if it makes you feel good and/or you have any evidence that it has any positive impact on your system at all.


Based on guidance from Aaron's answer as well as additional research, here is a quick write-up of the approach I took.

From what I can tell, the options for inspecting fragmentation of system base tables are limited. I went ahead and filed a Connect issue to provide better visibility, but in the meantime it seems that the options include things like examining the buffer pool or checking the average # of bytes per row.

I then created a procedure to perform `ALTER INDEX...REORGANIZE on all system base tables. Executing this procedure on a few of our most (ab)used dev servers showed that the cumulative size of the system base tables was trimmed by up to 50GB (with ~5MM user tables on the system, so clearly an extreme case).

One of our nightly maintenance tasks, which helps to clean up many of the user tables created by various unit tests and development, was previously taking ~50 minutes to complete. A combination of sp_whoisactive, sys.dm_os_waiting_tasks, and DBCC PAGE showed that the waits were dominated by I/O on the system base tables.

After the reorganization of all system base tables, the maintenance task dropped to ~15 minutes. There were still some I/O waits, but they were significantly diminished, perhaps due to a greater amount of the data remaining in cache and/or more readaheads due to lower fragmentation.

Therefore, my conclusion is that adding ALTER INDEX...REORGANIZE for system base tables into a maintenance plan may be a useful thing to consider, but likely only if you have a scenario where an unusual number of objects are being created on a database.