There is some subtraction going on within sp_spaceused, which grabs some of its information from the sysindexes table. If the columns in sysindexes are not synchronized with what's actually in your database, it is quite possible that certain columns in both resultsets of this procedure can contain negative values. This is especially true after a large number of insert/update/delete operations, or after a shrinkdatabase or shrinkfile, or after a large DTS import, or after dropping or truncating tables. These operations do not have any trigger-like activity that affects sysindexes, so the data it is using to calculate data file sizes and space usage are out of sync, and these deltas lead to strange values indeed.
To make sp_spaceused reflect your current space details, you can do one of two things:
- If you are worried about the whole database:
- If you are primarily interested in a single table:
| DBCC CHECKTABLE('tablename') |
If the rowcount you are getting is not right, using the UPDATEUSAGE statement above should correct that. For an absolutely correct count, you should use a count against the actual table:
| SELECT COUNT(*) FROM tablename |
And to be sure that parallelism issues are not invalidating the count (e.g. multiple threads could be scanning the same pages), limit the degree of parallelism to 1:
| SELECT COUNT(*) FROM tablename MAXDOP(1) |