简体   繁体   中英

Is there a way to remove allocated pages that are not associated with a table in SQL Server?

We have an "mdf" file for a database that has grown enough to fill up a 200GB disk on our SQL Server Windows machine. I used the query shown below to list the tables in that database with their "reserved" sizes. The result with the larges size is grouped with table and schema named "NULL".

How can I access and review and eventually remove these allocated pages from the database in order to shrink the "mdf" file's footprint on the disk?

Query (thanks to https://dba.stackexchange.com/users/30859/solomon-rutzky ):

use temp_db;
SELECT sch.[name], obj.[name], ISNULL(obj.[type_desc], N'TOTAL:') AS [type_desc],
   COUNT(*) AS [ReservedPages],
   (COUNT(*) * 8) AS [ReservedKB],
   (COUNT(*) * 8) / 1024.0 AS [ReservedMB],
   (COUNT(*) * 8) / 1024.0 / 1024.0 AS [ReservedGB]
FROM sys.dm_db_database_page_allocations(DB_ID(), NULL, NULL, NULL, DEFAULT) pa
INNER JOIN sys.all_objects obj
    ON obj.[object_id] = pa.[object_id]
INNER JOIN sys.schemas sch
    ON sch.[schema_id] = obj.[schema_id]
GROUP BY GROUPING SETS ((sch.[name], obj.[name], obj.[type_desc]), ())
ORDER BY [ReservedPages] DESC;

Results (top 3 rows plus header, with big "ReservedGB" highlighted):

name name type_desc ReservedPages ReservedKB ReservedMB ReservedGB
NULL NULL TOTAL: 15414665 123317320 120427.070312 117.604560851562
data crm_isc_sales_work_oppor_1b22e USER_TABLE 4451592 35612736 34778.062500 33.962951660156
data pr_data_ih_dim_action USER_TABLE 2705708 21645664 21138.343750 20.642913818359

I've tried restarting the SQL Server Database Engine (and Agent) as described here: https://learn.microsoft.com/en-us/sql/database-engine/configure-windows/start-stop-pause-resume-restart-sql-server-services?view=sql-server-ver16

That restart did not free up those allocated pages.

For non-table usage, i think Shrink is your friend but it's not without downsides.

In SSMS there's a handy report that displays reserved and actual size of tables. If you right click on the database you're interested in and select Reports -> Standard Reports -> Disk usage by top tables.

If there's a lot of "air" between reserved and taken space, you could rebuild your indexes (especially clustered (by using ALTER INDEX xxx ON yourtable REBUILD) and it will perhaps get some space back. Restarting server shouldn't make any difference me think.

You could shrink your db as well, but that usually has some problems with defragmentation.

If you have very large tables, something rebuild will take forever / not succeed, in that case you might wanna copy data to some other table and "rebuild" it manually by truncating original and copying it back. Your mileage may vary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM