我正在使用SQL Server 2005。
我有一个表,其行大小应为124个字节。它是所有的int或浮点数,没有NULL列(所以一切都是固定的宽度)。
只有一个索引,已群集。填充因子为0。
这是表格def:
create table OHLC_Bar_Trl
(
obt_obh_id int NOT NULL REFERENCES OHLC_Bar_Hdr (obh_id),
obt_bar_start_ms int NOT NULL,
obt_bar_end_ms int NOT NULL,
obt_last_price float NOT NULL,
obt_last_ms int NOT NULL,
obt_bid_price float NOT NULL,
obt_bid_size int NOT NULL,
obt_bid_ms int NOT NULL,
obt_bid_pexch_price float NOT NULL,
obt_ask_price float NOT NULL,
obt_ask_size int NOT NULL,
obt_ask_ms int NOT NULL,
obt_ask_pexch_price float NOT NULL,
obt_open_price float NOT NULL,
obt_open_ms INT NOT NULL,
obt_high_price float NOT NULL,
obt_high_ms INT NOT NULL,
obt_low_price float NOT NULL,
obt_low_ms INT NOT NULL,
obt_volume float NOT NULL,
obt_vwap float NOT NULL
)
go
create unique clustered index idx on OHLC_Bar_Trl (obt_obh_id,obt_bar_end_ms)
插入大量数据后,sp_spaceused将返回以下内容
name rows reserved data index_size unused
OHLC_Bar_Trl 117076054 29807664 KB 29711624 KB 92344 KB 3696 KB
显示大约(29807664 * 1024)/ 117076054 = 260字节/行的行数。
剩下的空间在哪里?
我是否需要运行一些DBCC命令来收紧这个表(我无法以正确的索引顺序插入行,所以可能只是内部碎片)?
答案 0 :(得分:2)
要更新“使用空间”统计信息,请使用sp_spaceused的第二个参数@updateusage:
EXEC sp_spaceused 'OHLC_Bar_Trl', 'true'
但是,我还首先运行ALTER INDEX ALL ON OHLC_Bar_Trl WITH REBUILD
来对数据进行碎片整理。
答案 1 :(得分:2)
您可以使用sys.dm_db_index_physical_stats获取有关数据在给定表中的存储方式的详细信息。这不是最明显的用法,这是我为第一次排除故障而构建的模板:
-- SQL 2005 - fragmentation & air bubbles
SELECT
ob.name [Table], ind.name [Index], ind.type_desc IndexType
,xx.partition_number PartitionNo
,xx.alloc_unit_type_desc AllocationTyp
,xx.index_level
,xx.page_count Pages
,xx.page_count / 128 Pages_MB
,xx.avg_fragmentation_in_percent AvgPctFrag
,xx.fragment_count
,xx.avg_fragment_size_in_pages AvgFragSize
,xx.record_count [Rows]
,xx.forwarded_record_count [ForwardedRows]
,xx.min_record_size_in_bytes MinRowBytes
,xx.avg_record_size_in_bytes AvgRowBytes
,xx.max_record_size_in_bytes MaxRowBytes
,case xx.page_count
when 0 then 0.0
else xx.record_count / xx.page_count
end AvgRowsPerPage
,xx.avg_page_space_used_in_percent AvgPctUsed
,xx.ghost_record_count
,xx.version_ghost_record_count
from sys.dm_db_index_physical_stats
(
db_id('MyDatabase')
,object_id('MyTable')
,null
,null
,'Detailed'
) xx
inner join sys.objects ob
on ob.object_id = xx.object_id
inner join sys.indexes ind
on ind.object_id = xx.object_id
and ind.index_id = xx.index_id
使用它来检查SQL是否认为该行的长度与您认为的一样长,或者是否在某处使用/浪费了额外的空间。
答案 2 :(得分:0)
对于您的表,是的,124字节似乎确实是正确的行大小,并且由于您的聚簇索引是唯一的,因此您不应该在唯一化器上浪费空间。那么让我们考虑一下它是如何组合在一起的:
(注意:计算来自Estimating the Size of a Clustered Index)
因此,您可以从中看到,您可以实现的绝对最小比率(使用total data size / max row size
的更简单的数学运算)大约是每行139个字节。
当然,您说在插入一堆数据后,您会立即看到这些统计信息 - 在自动递增时,群集密钥不的数据(IDENTITY
或NEWSEQUENTIALID
)列,因此可以 以真正顺序的方式插入。如果是这种情况,您可能会遭受大量页面拆分并需要对聚集索引进行碎片整理:
ALTER INDEX idx
ON OHLC_Bar_Trl
REORGANIZE -- or REBUILD
注意:我不确定此命令在SQL Server 2005上是否可用。旧语法为:
DBCC INDEXDEFRAG('MyDB', 'OHLC_Bar_Trl', indexnum)
您可能还需要缩小数据库以回收所有丢失的空间(尽管大多数人会建议不要缩小数据,除非您有充分的理由这样做。)