如何在 100 GB 表上创建聚集索引

use*_*849 8 index sql-server-2008 sql-server clustered-index

我有一个堆表,它占用大约 104 GB 的磁盘空间,几乎有 30 亿行。我正在尝试在 [ WeekEndingDate] 列上的该表上创建聚集索引。我在数据文件中有大约 200 gb 的空闲空间,在 tempdb 中有大约 280 gb 的空闲空间。

我尝试了两种不同的方法。首先是使用以下命令直接在表上创建索引:

CREATE CLUSTERED INDEX CX_WT_FOLD_HISTORY
ON WT_FOLD_HISTORY (WeekEndingDate ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = ON, 
IGNORE_DUP_KEY = OFF
, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, 
DATA_COMPRESSION = PAGE)
Run Code Online (Sandbox Code Playgroud)

我用SORT_IN_TEMPDB = ON和都试过了OFF。使用时ON它填满了 tempdb 并用OFF它填满了数据驱动器。

另一种方法是创建一个具有所需索引的新空白表,然后将堆中的记录插入到新表中。这在填充数据驱动器后也失败了。

关于做什么的任何其他建议。我读过的大多数内容都表明,在创建索引时,我需要大约 1.2 倍的表大小才能用作工作区。我有更多的方法,但它仍然失败。任何建议,将不胜感激。

这是我原来的堆表结构:

CREATE TABLE [dbo].[WT_FOLD_HISTORY](
[WeekEndingDate] [varchar](50) NULL,
[Division] [varchar](50) NULL,
[Store] [varchar](50) NULL,
[SKUNumber] [varchar](50) NULL,
[UPC] [varchar](50) NULL,
[SalesUnits] [varchar](50) NULL,
[SalesCost] [varchar](50) NULL,
[SalesRetail] [varchar](50) NULL,
[InventoryUnits] [varchar](50) NULL,
[InventoryCost] [varchar](50) NULL,
[InventoryRetail] [varchar](50) NULL,
[OnOrderUnits] [varchar](50) NULL,
[OnOrderCost] [varchar](50) NULL,
[OnOrderRetail] [varchar](50) NULL,
[ReceiptUnits] [varchar](50) NULL,
[ReceiptCost] [varchar](50) NULL,
[ReceiptRetail] [varchar](50) NULL,
[PermanentMarkdowns] [varchar](50) NULL,
[ReturnsToVendor] [varchar](50) NULL,
[POSMarkdowns] [varchar](50) NULL,
[TimeFK] [smallint] NULL,
[LocationFK] [int] NULL,
[ItemFK] [int] NULL
) ON [AcademySports_DataFG1]
Run Code Online (Sandbox Code Playgroud)

RDF*_*ozz 3

如果您短期需要磁盘空间,一种选择是:

  1. 暂时缩小 tempdb,在该驱动器上释放看起来安全的尽可能多的空间。
  2. 在 tempdb 驱动器上为表所在的数据库创建辅助数据文件。
  3. 将聚集索引添加到表中。
  4. 通过将所有数据迁移出辅助文件来缩小辅助文件。
  5. 删除辅助文件。
  6. 确保允许 tempdb 文件增长到原来的大小。
  7. 在表的数据库中重建索引(删除辅助文件将导致一些碎片)。

注意:正如其他人所建议的,我只会在暂时从相关表中删除非聚集索引之类的事情之后才执行此操作。特别是,这将允许添加聚集索引的速度更快,因为无论如何非聚集索引都必须重建(有了聚集索引,索引键用于定位表本身中的行) 。

这实际上是另一点——聚集索引上的键有多宽?如果您确实有非聚集索引,并且聚集索引上的键明显比堆中的指针宽,那么在创建聚集索引后,非聚集索引将消耗更多空间。

如果簇键由多列组成,甚至由一个大列(例如,varchar平均长度为 25 或更长的列)组成,您可能需要考虑使用代理键(通常是单调递增的值,以获得最佳INSERT性能)。