Sql-Server

了解兩張表使用的儲存空間的差異

  • May 17, 2019

我有兩張表,其中一張或多或少包含另一張的數據子集。我從第一個表中刪除了一些數據,作為歷史數據插入到第二個表中。

這些是定義:

CREATE TABLE [dbo].[CIC_DESLUNGHE](
   [CD_CIC_DESLUNGHE] [bigint] IDENTITY(1,1) NOT NULL,
   [CD_CIC_PRODUZIONE] [bigint] NOT NULL,
   [CD_CIC_OPERAZIONI] [bigint] NOT NULL,
   [AFNMPROG] [int] NOT NULL,
   [AFDSLINE] [nvarchar](max) NULL,
CONSTRAINT [PK_CIC_DESLUNGHE] PRIMARY KEY CLUSTERED 
(
   [CD_CIC_DESLUNGHE] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 99) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO


CREATE TABLE [dbo].[CIC_DESLUNGHE_STORICI](
   [CD_CIC_DESLUNGHE_STORICI] [bigint] IDENTITY(1,1) NOT NULL,
   [CD_CIC_PRODUZIONE_STORICI] [bigint] NOT NULL,
   [CD_CIC_OPERAZIONI_STORICI] [bigint] NOT NULL,
   [AFNMPROG] [int] NOT NULL,
   [AFDSLINE] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_CIC_DESLUNGHE_STORICI_1] PRIMARY KEY CLUSTERED 
(
   [CD_CIC_DESLUNGHE_STORICI] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

第二個表包含一個數據子集,我需要它作為數據的歷史化。

Table                   Rows        TotalSpace MB
---------------------   ----------  -------------
CIC_DESLUNGHE_STORICI   12.709.497  48214,75
CIC_DESLUNGHE           24.827.337  5675,49

讓我吃驚的是使用的總儲存空間。子集表使用的空間是另一個表的 10 倍。

知道為什麼會這樣嗎?

我嘗試重建 的聚集索引CIC_DESLUNGHE_STORICI,但儲存僅從 48 GB 下降到 47 GB。

- 編輯 -

這是我通過 Josh Darnell 的查詢得到的結果

CIC_DESLUNGHE

CIC_DESLUNGHE_STORICI

根據給出的資訊,一種解釋是儲存在nvarchar(max)列中的數據大小過去比現在大得多。

  • 約 1200 萬行歷史記錄,平均每行 3.88 KB
  • 約 2400 萬個實時行,平均每行 0.23 KB

您可以使用動態管理函式sys.dm_db_index_physical_stats對這兩個表中的每一個進行仔細檢查,特別是查看“avg_record_size_in_bytes”列。像這樣的東西:

SELECT 
   DB_NAME(ips.database_id),
   OBJECT_NAME(ips.[object_id]),
   ips.index_id,
   ips.index_type_desc,
   ips.index_level,
   ips.alloc_unit_type_desc,
   ips.page_count,
   ips.record_count,
   ips.min_record_size_in_bytes,
   ips.max_record_size_in_bytes,
   ips.avg_record_size_in_bytes
FROM sys.dm_db_index_physical_stats 
(
   DB_ID(N'YourDatabaseName'), 
   OBJECT_ID(N'CIC_DESLUNGHE'), 
   NULL, 
   NULL , 
   'DETAILED'
) ips;

SELECT 
   DB_NAME(ips.database_id),
   OBJECT_NAME(ips.[object_id]),
   ips.index_id,
   ips.index_type_desc,
   ips.index_level,
   ips.alloc_unit_type_desc,
   ips.page_count,
   ips.record_count,
   ips.min_record_size_in_bytes,
   ips.max_record_size_in_bytes,
   ips.avg_record_size_in_bytes
FROM sys.dm_db_index_physical_stats 
(
   DB_ID(N'YourDatabaseName'), 
   OBJECT_ID(N'CIC_DESLUNGHE_STORICI'), 
   NULL, 
   NULL , 
   'DETAILED'
) ips;

比較兩個查詢的結果,看看是否有任何令人驚訝的差異。

我在函式呼叫中留下了其他過濾器,因為這也會顯示非聚集索引。您沒有提到您是如何得出問題中的數字的,但是如果它們在表格中包含 NC 索引,那麼這些可能會導致大小差異。

引用自:https://dba.stackexchange.com/questions/238331