Microsoft SQL Server:现有表新PK和索引问题

Microsoft SQL Server : existing table new PK & index issue

提问人:NDallasDan 提问时间:10/25/2023 最后编辑:marc_sNDallasDan 更新时间:10/26/2023 访问量:50

问:

我有一个旧的数据库,不幸的是,在设计时选择了最大的表之一,其中包含照片(称为表)并具有 PK 类型。此表有 195k 行,显然几乎是 100% 的碎片。我想在这个桌子上建立一个新的PK,但有一些问题和考虑Photosuniqueidentifier

数据背景

表的行大小预计不会超出 (int) 的边界。此外,与表的 PK 没有 FK 关系。如前所述,表中有 195k 行。有一个潜在的考虑因素:called 中有一个非唯一列,它与另一个称为 的表的 PK 具有 FK 关系。该键的性质是这样的,它是一个递增计数器 (int)。表中的PK和表中的FK之间存在一>多关系。PhotosPhotosPhotosJob_IDDeliveryTicketJob_IDDeliveryTicketJob_IDPhotos

我的担忧源于碎片化和索引的角度,我的问题是:

  1. 如何将PK约束添加为非null的新列,并使用类型(int)的新递增索引填充现有行?New_IDPhotos

  2. 我是否应该以及如何在表上的 FK 值上创建新的聚集索引?请注意,通过程序逻辑,对表的大多数查询将针对 FK 值,但绝不会针对表的现有或任何新 PK。该表的最快索引将位于 FK 关系列上。PhotosPhotosJob_IDPhotosPhotosJob_ID

  3. 有没有更好的方法可以以某种方式创建一个新的 PK,该 PK 从 的最低(非唯一 on )值开始计数,以便默认索引 (PK) 成为最快的索引?PhotosJob_ID

以下是以下声明:CREATE TABLEPhotos

CREATE TABLE [dbo].[Photos]
(
    [ID] [uniqueidentifier] ROWGUIDCOL NOT NULL,
    [Photo_Serial_Number] [int] IDENTITY(1,1) NOT NULL,
    [Job_ID] [int] NOT NULL,
    [Photo_Upload_Disposition_Type] [int] NOT NULL,
    [NET_Rating] [real] NULL,
    [Rating_ID] [int] NULL,
    [Image_Data] [varbinary](max) FILESTREAM  NOT NULL,
    [File_Name] [nvarchar](50) NOT NULL,
    [File_Extension] [varchar](5) NOT NULL,
    [Image_Comments] [nvarchar](1000) NULL,

     CONSTRAINT [PK_Photos] PRIMARY KEY CLUSTERED (ID)
);

我正处于探索阶段。这是一个生产数据库,虽然它将被备份并测试更改,因为它必须在维护时段内发生,但尚未进行此类更改。

sql-server t-sql sql-server-2008-r2

评论

0赞 Martin Smith 10/25/2023
您如何证明这种程度的碎片化导致了任何需要修复的问题?“几乎100%碎片化”本身并不是问题。您有什么实际性能问题?
0赞 Dan Guzman 10/25/2023
为什么不使用现有列,而不是添加列呢?我将创建一个复合聚集主键约束,并通过 优化查询。New_IdPhoto_Serial_NumberIDENTITYJob_IDPhoto_Serial_NumberJob_ID
0赞 siggemannen 10/25/2023
性能问题很可能是由于 varbinary 的东西或占用一些空间的注释造成的,而不是 UNIQUEIDENTIFIER。150k 行并不多,特别是因为我认为 Filestream 内容不存储在页面上,因此遍历表应该不会花费很多时间。您有哪些疑问是?无论您做什么,SELECT * 都可能很慢
0赞 NDallasDan 10/25/2023
我理解,还有其他我不担心碎片化的表。当按Job_ID查询时,这个会降低性能。 @DanGuzman 我认为您建议的复合键可能是一个可行的解决方案。我在这里显然不是很精明,我熟悉唯一性的复合键,这本身不是这里的问题,但是您似乎建议该键上的相应聚集索引将提高部分键(即Job_ID)的查询性能。我理解正确吗?

答:

1赞 David Browne - Microsoft 10/25/2023 #1

此表有 195k 行,显然几乎是 100% 的碎片。

那又怎样?您是否有可衡量的性能问题?只需添加默认值 NEWSEQUENTIALID 即可生成顺序 GUID,以减少今后的碎片。

评论

0赞 NDallasDan 10/25/2023
是的,存在可衡量的性能问题,我很欣赏您的建议,这可以缓解未来的问题,但不能解决现有行的问题。大多数查询都位于Job_ID列上,该列未编制索引(或在该表上是唯一的)。例如,我刚刚对所有Job_ID> 39000(只有 39786 Job_ID')运行了一个查询,执行起来花了 10 多分钟。
0赞 David Browne - Microsoft 10/25/2023
听起来您需要对Job_ID进行索引。 外键列通常应该被索引。如果您主要按Job_ID访问此表,则将其添加为聚集索引的前导列可能会有所帮助。