gpt4 book ai didi

sql - 如何让SQL Server索引占用更少的空间?

转载 作者:太空狗 更新时间:2023-10-30 01:58:38 25 4
gpt4 key购买 nike

我有一个由某个应用程序创建的数据库。整个数据库超过 50 GB,备份出现了一些问题,我的任务是让这个数据库尽可能小。

特别是一张表很大(22gb),其中16.5gb是索引,剩下的5.5gb是数据。它包含略多于 12 000 000 行。

你能告诉我是否可以收缩索引?我已经尝试过重建、重组、重新创建聚簇索引、dbcc cleantable。我还知道 nvarchar 类型的大小是 varchar 的两倍,所以我将列类型更改为 varchar,但多亏了这一点,我只节省了大约 2 gb(1 gb 数据和 1 gb 索引)。

这是这个表的一个 sql(fld0 和 fld1 总是 NULL):

CREATE TABLE [dbo].[DOC8](
[ASSOCIATION] [nvarchar](64) NULL DEFAULT (NULL),
[DOCID] [char](32) NOT NULL,
[FLD0] [nvarchar](255) NULL DEFAULT (NULL),
[FLD1] [nvarchar](2048) NULL DEFAULT (NULL),
[FLD10] [nvarchar](255) NULL DEFAULT (NULL),
[FLD2] [nvarchar](32) NULL DEFAULT (NULL),
[FLD3] [nvarchar](255) NULL DEFAULT (NULL),
[FLD4] [nvarchar](255) NULL DEFAULT (NULL),
[FLD5] [datetime] NULL DEFAULT (NULL),
[FLD6] [nvarchar](255) NULL DEFAULT (NULL),
[FLD7] [nvarchar](255) NULL DEFAULT (NULL),
[FLD8] [nvarchar](255) NULL DEFAULT (NULL),
[FLD9] [datetime] NULL DEFAULT (NULL),
[PARENTID] [char](32) NULL DEFAULT (NULL),
[POOLID] [char](32) NULL DEFAULT (NULL),
[PROPERTIES] [ntext] NULL DEFAULT (NULL),
[FLD11] [nvarchar](255) NULL DEFAULT (NULL),
[FLD12] [nvarchar](255) NULL DEFAULT (NULL),
PRIMARY KEY CLUSTERED
(
[DOCID] 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
CREATE NONCLUSTERED INDEX [DOC8_IDX_0] ON [dbo].[DOC8]
(
[ASSOCIATION] ASC,
[PARENTID] ASC,
[POOLID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [DOC8_IDX_1] ON [dbo].[DOC8]
(
[POOLID] ASC,
[FLD0] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [DOC8_IDX_10] ON [dbo].[DOC8]
(
[POOLID] ASC,
[FLD11] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [DOC8_IDX_11] ON [dbo].[DOC8]
(
[POOLID] ASC,
[FLD12] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [DOC8_IDX_2] ON [dbo].[DOC8]
(
[POOLID] ASC,
[FLD2] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [DOC8_IDX_3] ON [dbo].[DOC8]
(
[POOLID] ASC,
[FLD3] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [DOC8_IDX_4] ON [dbo].[DOC8]
(
[POOLID] ASC,
[FLD4] ASC,
[FLD5] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [DOC8_IDX_5] ON [dbo].[DOC8]
(
[POOLID] ASC,
[FLD6] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [DOC8_IDX_6] ON [dbo].[DOC8]
(
[POOLID] ASC,
[FLD7] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [DOC8_IDX_7] ON [dbo].[DOC8]
(
[POOLID] ASC,
[FLD8] ASC,
[FLD9] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [DOC8_IDX_8] ON [dbo].[DOC8]
(
[POOLID] ASC,
[FLD10] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [DOC8_IDX_9] ON [dbo].[DOC8]
(
[PARENTID] ASC,
[POOLID] ASC,
[DOCID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

最佳答案

查看表定义

主键:

  • 您有一个 char(32) 聚簇索引。这 32 个字节出现在每个 非聚集索引中

列:

  • 为什么是 char(32)? -> 可变字符(32)
  • 为什么使用 nvarchar()? -> 变量
  • 为什么是日期时间? -> 小日期时间
  • 为什么是 ntext? -> 可变字符(最大值)

索引:

  • 您能否使用 INCLUDE 而不是使用键列

您的主要问题是聚集索引的选择不当。如果你不能解决这个问题,那么几乎所有其他事情都毫无意义:除非你删除数据......

当您更改为 varchar 时,您节省了 22GB 中的 2GB。这是 9%,这在没有其他优化的情况下是相当合理的。它还表明您不需要 nvarchar...

如果更改为 int 代理键,则每个非聚集索引每行可节省 28 个字节。最小为 3.7 GB (12 x 12,000,000 x 28),但由于每页行数更多,因此会更多。而且它对客户端代码是透明的。

然后您开始检查索引使用...

但是,您应该考虑容量规划和数据增长规划。我在此处建议的更改将降低增长率 以及当前大小,但如果您还需要 5000 万行,则需要为此进行规划。例如,您可以压缩备份吗?

关于sql - 如何让SQL Server索引占用更少的空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4553460/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com