2010-06-07 46 views
0

我正在使用SQL Server 2005.本表中剩餘空間在哪裏?

我有一個表的行大小應該是124個字節。這是所有整數或浮點數,沒有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 

其示出大約的ROWSIZE(29807664 * 1024後)/ 117076054 = 260字節/行。

剩下的空間在哪裏?

是否需要運行一些DBCC命令來收緊此表(我無法以正確的索引順序插入行,因此可能只是內部碎片)?

+0

如果您顯示實際的列和鍵(例如,您的聚簇索引是否在唯一的單列主鍵上?) – Aaronaught 2010-06-07 14:01:04

+0

添加了表def ..... – 2010-06-07 15:16:16

回答

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認爲該行,只要你覺得是,或者如果有額外的空間被使用/浪費在某個地方。

+0

好吧,我開始運行,我的機器幾乎停下來。我仍然在執行導入工作,我會等到完成並給它一個旋轉。我假設它讀取了大部分數據頁面(至少,我認爲這是開始刺激SQL Server活動的原因)。儘管如此,給出了一個小表格的輸出結果。 – 2010-06-07 14:25:17

+0

在加載時閱讀BOL中的sys.dm_db_index_physical_stats。我沒有選擇它提供的所有信息,並且可能存在適用於您的環境的內容。 – 2010-06-07 14:32:52

+0

剛剛完成了一個ALTER INDEX REORGANIZE,桌子大約是我期待的大小(即減少了一半)。 – 2010-06-08 19:43:29

2

要更新「已用空間」的統計,使用sp_spaceused第二個參數@updateusage:

EXEC sp_spaceused 'OHLC_Bar_Trl', 'true' 

不過,我還跑ALTER INDEX ALL ON OHLC_Bar_Trl WITH REBUILD第一碎片整理的數據。

+0

這樣會更容易回答那是ALTER INDEX是否需要足夠的空間來完整複製數據?如果是這樣,我想我會敬酒。在這種情況下,我可能需要將數據發送出去(到網絡磁盤),然後重新輸入數據。在過去的日子裏,這往往會實現我的目標。 – 2010-06-07 13:53:56

0

對於你的表,是的,124字節似乎是正確的行大小,並且由於你的聚簇索引是唯一的,所以你不應該在唯一化程序上浪費空間。因此,讓我們考慮如何結合在一起的:

  • 頁面大小= 8 KB(8192個字節)
    • 頭= 96個字節
    • 可用於數據= 8096個字節
  • 行大小(固定數據)= 124字節
    • 頭= 4字節
    • 空位圖= 5個字節(21列)
  • 每頁行數=(一百三十七分之八千○九十六)= 59
  • 可變數據的尺寸= 2(0變量列)
  • 總計= 135個字節
  • 總行數= 117076054
  • 總頁數=59分之117076054= 1984440
  • 實際尺寸= 1984440 * 8 KB = 15875520 KB

(注:計算是從Estimating the Size of a Clustered Index派生)

所以你可以從這個看出,絕對最低比你能夠實現(使用total data size/max row size的更簡單的數學運算)大約是每行139個字節。

當然,你說你後立即看到這些統計數據中插入一組數據 - 爲其聚集鍵是上的自動遞增(IDENTITYNEWSEQUENTIALID)列和數據將因此可以將而不是以真正順序的方式插入。如果是這樣的話,你很可能從頁面拆分的數量巨大的痛苦和需要進行碎片整理的聚集索引:

ALTER INDEX idx 
ON OHLC_Bar_Trl 
REORGANIZE -- or REBUILD 

注:我不知道,如果這個命令可用SQL Server 2005中的年長語法是:

DBCC INDEXDEFRAG('MyDB', 'OHLC_Bar_Trl', indexnum) 

您可能還需要收縮數據庫以回收全部丟失的空間(雖然多數人會建議對數據縮水,除非你有一個很好的理由這樣做)。

+0

是的,那些calcs看起來是正確的....我是否總是需要5個字節的空數組(表中沒有空值)?不像5字節會打破我,無論哪種方式。我在另一個答案中問到了,我也會在這裏問:你知道REORG/REBUILD是否需要足夠的空間來複製表格,或者它是否到位?我可能必須BCP取出數據並將其讀回,或者更改插入程序以緩存結果,直到它有足夠的順序寫出它們,否則。我沒有足夠的空間來做副本的35Gb表,上帝只知道進入日誌的內容...... – 2010-06-07 17:22:43

+0

@Eric:這5個字節是「保留空間」 - 如果你真的開始添加很多可爲空的列,那麼數字將增長。至於你的第二個問題,'ALTER INDEX REORGANIZE'需要一些額外的空間,但不是整個表的大小,'REBUILD'可能需要索引的完整分段大小。但是,如果此數據尚未投入生產,那麼您可以刪除並重新創建索引,這相當於重建,但不需要任何額外空間AFAIK。 – Aaronaught 2010-06-07 17:44:34

+0

ALTER INDEX從SQL Server 2005開始 – gbn 2010-06-07 18:25:20