我发现一个客户数据库的大小在昨天和今天之间激增。经过调查,我在表模式中发现了一个设计问题,但在进行了一些数学运算后,我知道已将 55MB 的数据添加到表中,但表大小现在为 1GB,而表的原始大小为 70MB。
有关其他信息,通过添加 2000 多行且varchar(max)
字段填充数据来添加 55MB数据。
这是之前/之后的分析:
你能向我解释一下为什么一个表需要 70MB 现在在添加 55MB 数据后需要 1GB 吗?
上没有任何索引 varchar(max)
可用空间非常低,与自增长无关。并且自动增长不是用百分比配置的,而是用固定的增长大小配置的。
这是表的创建脚本:
USE [DuoClient20140003]
GO
/****** Object: Table [dbo].[tContactHistory] Script Date: 23/05/2016 10:53:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[tContactHistory](
[KeyCH] [int] IDENTITY(1,1) NOT NULL,
[DateCH] [datetime] NULL,
[KeyType] [int] NULL,
[KeyF] [int] NULL,
[KeyI] [int] NULL,
[KeyCA] [int] NULL,
[Content] [varchar](max) NULL,
[KeyCom] [int] NULL,
[KeyMH] [bigint] NULL,
[KeyH] [bigint] NULL,
CONSTRAINT [tContactHistory_PK] PRIMARY KEY CLUSTERED
(
[KeyCH] 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
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[tContactHistory] WITH NOCHECK ADD CONSTRAINT [tAddrCarnet_tContactHistory_FK1] FOREIGN KEY([KeyCA])
REFERENCES [dbo].[tAddrCarnet] ([KeyCA])
GO
ALTER TABLE [dbo].[tContactHistory] CHECK CONSTRAINT [tAddrCarnet_tContactHistory_FK1]
GO
ALTER TABLE [dbo].[tContactHistory] WITH NOCHECK ADD CONSTRAINT [tComments_tContactHistory_FK1] FOREIGN KEY([KeyCom])
REFERENCES [dbo].[tComments] ([KeyCom])
GO
ALTER TABLE [dbo].[tContactHistory] CHECK CONSTRAINT [tComments_tContactHistory_FK1]
GO
ALTER TABLE [dbo].[tContactHistory] WITH NOCHECK ADD CONSTRAINT [tFoyers_tContactHistory_FK1] FOREIGN KEY([KeyF])
REFERENCES [dbo].[tFoyers] ([KeyF])
GO
ALTER TABLE [dbo].[tContactHistory] CHECK CONSTRAINT [tFoyers_tContactHistory_FK1]
GO
ALTER TABLE [dbo].[tContactHistory] WITH NOCHECK ADD CONSTRAINT [tIndivs_tContactHistory_FK1] FOREIGN KEY([KeyI])
REFERENCES [dbo].[tIndivs] ([KeyI])
GO
ALTER TABLE [dbo].[tContactHistory] CHECK CONSTRAINT [tIndivs_tContactHistory_FK1]
GO
ALTER TABLE [dbo].[tContactHistory] WITH NOCHECK ADD CONSTRAINT [tMailHistory_tContactHistory] FOREIGN KEY([KeyH])
REFERENCES [dbo].[tMailHistory] ([KeyH])
GO
ALTER TABLE [dbo].[tContactHistory] CHECK CONSTRAINT [tMailHistory_tContactHistory]
GO
ALTER TABLE [dbo].[tContactHistory] WITH NOCHECK ADD CONSTRAINT [tModifsHistory_tContactHistory_FK1] FOREIGN KEY([KeyMH])
REFERENCES [dbo].[tModifsHistory] ([KeyMH])
GO
ALTER TABLE [dbo].[tContactHistory] CHECK CONSTRAINT [tModifsHistory_tContactHistory_FK1]
GO
ALTER TABLE [dbo].[tContactHistory] WITH NOCHECK ADD CONSTRAINT [tTabShort_tContactHistory_FK1] FOREIGN KEY([KeyType])
REFERENCES [dbo].[tTabShort] ([KeyT])
GO
ALTER TABLE [dbo].[tContactHistory] CHECK CONSTRAINT [tTabShort_tContactHistory_FK1]
GO
ALTER TABLE [dbo].[tContactHistory] WITH NOCHECK ADD CONSTRAINT [tContactHistoryKeyI_Chk] CHECK (([KeyI]>=(1)))
GO
ALTER TABLE [dbo].[tContactHistory] CHECK CONSTRAINT [tContactHistoryKeyI_Chk]
GO
Run Code Online (Sandbox Code Playgroud)
系统过程sp_spaceused告诉您数据是如何分布的,并且通常足够准确。运行以下简单的 TSQL:
DECLARE @R TABLE (TabName sysname, [Row Count] bigint, Reserved varchar(128), Data varchar(128), [Idx Size] varchar(128), Unused varchar(128))
INSERT INTO @R
exec sp_spaceused 'tContactHistory'
SELECT TabName
, [Row Count]
, cast(round(cast(replace(Reserved, ' KB','') as dec(32,2))/1024,2) as dec(32,2)) [Reserved MB]
, cast(round(cast(replace(Data, ' KB','') as dec(32,2))/1024,2) as dec(32,2)) [Data MB]
, cast(round(cast(replace([Idx Size], ' KB','') as dec(32,2))/1024,2) as dec(32,2)) [Idx Size MB]
, cast(round(cast(replace(Unused, ' KB','') as dec(32,2))/1024,2) as dec(32,2)) [Unused MB]
FROM @R
Run Code Online (Sandbox Code Playgroud)
告诉我们你发现了什么。如果填充因子、数据类型或只是简单的过分热心索引存在问题,这至少应该提供足够的线索,告诉我们下一步该往哪里走。
更新:结果是:
那么你的结果很奇怪。这意味着实际使用了数据。我还看到有人在你如何验证数据大小之前已经问过你,你回答说你是通过从字段大小计算它来完成的。你确定你这样做正确吗?是否有可能引入了您看不到的空字符串或特殊字符,但仍然占用空间?或者您正在处理而CHAR
不是VARCHAR
具有相同最终结果的字段?
DATALENGTH
例如,请参阅函数以检查可变长度列的长度。
-- For example:
SELECT DATALENGTH(myVarCharColumnName) DLen
FROM tContactHistory
ORDER BY DLen desc
-- Note by checking the column type and storage size from MSDN,
-- you can now use this information to calculate the storage size.
Run Code Online (Sandbox Code Playgroud)
此外,您是否通过例如将部分数据复制到新的虚拟表来测试这个假设,看看会发生什么?喜欢
SELECT TOP 1000 *
INTO myStorageSizeTest
FROM tContactHistory
WHERE ... -- Insert whatever condition here to only select the new rows where this space problem appeared
Run Code Online (Sandbox Code Playgroud)
等等。不要害怕测试和发挥创意。
归档时间: |
|
查看次数: |
212 次 |
最近记录: |