外键关系可能存在性能问题

时间:2014-04-08 20:29:46

标签: sql-server sql-server-2008 foreign-keys foreign-key-relationship database-performance

我们有一个User表格,GUID又称uniqueidentifier作为PK。数据库中几乎所有其他表都与 4 FK引用绑定在此表中。当我查看DB图表时,由于UserCreatedByCreatedByProxyUpdatedBy表,它看起来像是一条100车道高速公路{1}}外键。

我已经过了这个项目并且已经开始生产,并且已经出现了性能问题。

我想知道当用户列表开始增长时,这种UpdatedByProxy模式是否会导致重大的成长痛苦。我们是否会因此而遇到更多性能问题,或者如果我们创建索引将保持外​​键导致索引变大。我只是不记得之前我曾经做过的网站,之前有过这样的外键,而且我担心将来会打样/修复它。我真的只是想证明是否保留或删除外键或修改结构以便

用户表:

DB

另一个引用用户的表:

    CREATE TABLE [dbo].[aspnet_Users](
        [ApplicationId] [uniqueidentifier] NOT NULL,
        [UserId] [uniqueidentifier] NOT NULL, -- ***** Here is the PK
        [UserName] [nvarchar](256) NOT NULL,
        [LoweredUserName] [nvarchar](256) NOT NULL,
        [MobileAlias] [nvarchar](16) NULL,
        [IsAnonymous] [bit] NOT NULL,
        [LastActivityDate] [datetime] NOT NULL,
    PRIMARY KEY NONCLUSTERED 
    (
        [UserId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]

1 个答案:

答案 0 :(得分:1)

  

在它已经过去之后,我被带到了这个项目   已经在生产中,并且存在性能问题。

你不能说出那些 的性能问题,所以我将我的评论限制在外键上。

  

当我查看DB图时,它看起来像一条100车道高速公路   由于CreatedBy,CreatedByProxy,在User表之外,   UpdatedBy,UpdatedByProxy外键。

当我看到这样的列时,我不得不问它们是否包含有关业务实体的信息 - 在这种情况下是一个人的电子邮件地址 - 或者有关实体恰好居住的行的信息。

看起来就像它们包含有关该行的信息一样。 (但我可能是错的。)

如果他们包含有关该行的信息,并且在大多数查询中不需要它们,则可以将它们移动到另一个表中。如果移动它们,则必须更加小心地将行插入dbo.Email。

CREATE TABLE [dbo].[Email](
    [EmailId] [int] IDENTITY(1,1) NOT NULL,
    [PersonId] [int] NULL,
    [InstitutionId] [int] NULL,
    [EmailTypeId] [int] NOT NULL,
    [EmailAddress] [varchar](254) NOT NULL,
    [IsFlaggedImportant] [bit] NOT NULL,
    [IsDistrictRecord] [bit] NOT NULL,
    [IsActive] [bit] NOT NULL,
    CONSTRAINT [PK_Email] PRIMARY KEY CLUSTERED ([EmailID])
);

CREATE TABLE [dbo].[Email_audit](
    [EmailID] [int] PRIMARY KEY REFERENCES [Email] ([EmailID]),
    [Created] [datetime] NOT NULL,
    [CreatedBy] [uniqueidentifier] NOT NULL, -- ***** FK 1
    [Proxy] [uniqueidentifier] NULL,         -- ***** FK 2
    [Updated] [datetime] NULL,
    [UpdatedBy] [uniqueidentifier] NULL,     -- ***** FK 3
    [UpdateProxy] [uniqueidentifier] NULL    -- ***** FK 4
);

这些类型的表通常用于提供某种类审计跟踪。是否可以级联删除是依赖于应用程序的。在部分应用中,您需要在此处存储电子邮件地址而不是电子邮件ID号,并使用外键引用。 (这允许从dbo.Email中删除行,同时保留某些有关该行发生的事件的信息。)

移动这些列会将dbo.Email中行的宽度减少大约80个字节,而不计算开销。 通常提高了SELECT语句在其移动的表中的性能。 (行数越窄;每页行数越多。)

但是,移动这些列会使插入和更新行变得复杂。所有插入和更新都必须打两个表。