Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 外键关系可能存在的性能问题_Sql Server_Sql Server 2008_Foreign Keys_Foreign Key Relationship_Database Performance - Fatal编程技术网

Sql server 外键关系可能存在的性能问题

Sql server 外键关系可能存在的性能问题,sql-server,sql-server-2008,foreign-keys,foreign-key-relationship,database-performance,Sql Server,Sql Server 2008,Foreign Keys,Foreign Key Relationship,Database Performance,我们有一个User表,其中GUIDakauniqueidentifier作为PK。数据库中几乎所有其他表都使用4FK引用与此表关联。当我看DB图表时,它看起来像一条100车道的高速公路从用户表中出来,因为CreatedBy,CreatedByProxy,UpdatedBy,UpdatedBy外键 我被带到这个项目是因为它已经过了初始阶段,并且已经投入生产,并且存在性能问题 我想知道,当用户列表开始增长时,这种DB模式是否会导致严重的成长问题。因此,我们将来会遇到更多的性能问题吗?或者,如果我们创

我们有一个
User
表,其中
GUID
aka
uniqueidentifier
作为
PK
。数据库中几乎所有其他表都使用4
FK
引用与此表关联。当我看
DB
图表时,它看起来像一条100车道的高速公路从
用户表中出来,因为
CreatedBy
CreatedByProxy
UpdatedBy
UpdatedBy
外键

我被带到这个项目是因为它已经过了初始阶段,并且已经投入生产,并且存在性能问题

我想知道,当用户列表开始增长时,这种
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]
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,
    [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
 CONSTRAINT [PK_Email] PRIMARY KEY CLUSTERED 
(
    [EmailId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Email] ADD  CONSTRAINT [DF_Email_IsPrimary]  DEFAULT ((0)) FOR [IsFlaggedImportant]
GO

ALTER TABLE [dbo].[Email] ADD  CONSTRAINT [DF_Email_IsDistrictRecord]  DEFAULT ((0)) FOR [IsDistrictRecord]
GO

ALTER TABLE [dbo].[Email] ADD  CONSTRAINT [DF_Email_IsActive]  DEFAULT ((0)) FOR [IsActive]
GO

ALTER TABLE [dbo].[Email] ADD  CONSTRAINT [DF_Email_Created]  DEFAULT (getdate()) FOR [Created]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_CreatedByUser] FOREIGN KEY([CreatedBy])
REFERENCES [dbo].[aspnet_Users] ([UserId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_CreatedByUser]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_EmailType] FOREIGN KEY([EmailTypeId])
REFERENCES [dbo].[EmailType] ([EmailTypeId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_EmailType]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_Institution] FOREIGN KEY([InstitutionId])
REFERENCES [dbo].[Institution] ([InstitutionId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_Institution]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_Person] FOREIGN KEY([PersonId])
REFERENCES [dbo].[Person] ([PersonId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_Person]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_ProxyByUser] FOREIGN KEY([Proxy])
REFERENCES [dbo].[aspnet_Users] ([UserId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_ProxyByUser]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_ProxyUpdateByUser] FOREIGN KEY([UpdateProxy])
REFERENCES [dbo].[aspnet_Users] ([UserId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_ProxyUpdateByUser]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_UpdatedByUser] FOREIGN KEY([UpdatedBy])
REFERENCES [dbo].[aspnet_Users] ([UserId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_UpdatedByUser]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [CK_Email_Person_Or_Institution] CHECK  (([PersonId] IS NOT NULL AND [InstitutionId] IS NULL OR [PersonId] IS NULL AND [InstitutionId] IS NOT NULL))
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [CK_Email_Person_Or_Institution]
GO
另一个引用用户的表:

    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]
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,
    [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
 CONSTRAINT [PK_Email] PRIMARY KEY CLUSTERED 
(
    [EmailId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Email] ADD  CONSTRAINT [DF_Email_IsPrimary]  DEFAULT ((0)) FOR [IsFlaggedImportant]
GO

ALTER TABLE [dbo].[Email] ADD  CONSTRAINT [DF_Email_IsDistrictRecord]  DEFAULT ((0)) FOR [IsDistrictRecord]
GO

ALTER TABLE [dbo].[Email] ADD  CONSTRAINT [DF_Email_IsActive]  DEFAULT ((0)) FOR [IsActive]
GO

ALTER TABLE [dbo].[Email] ADD  CONSTRAINT [DF_Email_Created]  DEFAULT (getdate()) FOR [Created]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_CreatedByUser] FOREIGN KEY([CreatedBy])
REFERENCES [dbo].[aspnet_Users] ([UserId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_CreatedByUser]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_EmailType] FOREIGN KEY([EmailTypeId])
REFERENCES [dbo].[EmailType] ([EmailTypeId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_EmailType]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_Institution] FOREIGN KEY([InstitutionId])
REFERENCES [dbo].[Institution] ([InstitutionId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_Institution]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_Person] FOREIGN KEY([PersonId])
REFERENCES [dbo].[Person] ([PersonId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_Person]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_ProxyByUser] FOREIGN KEY([Proxy])
REFERENCES [dbo].[aspnet_Users] ([UserId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_ProxyByUser]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_ProxyUpdateByUser] FOREIGN KEY([UpdateProxy])
REFERENCES [dbo].[aspnet_Users] ([UserId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_ProxyUpdateByUser]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_UpdatedByUser] FOREIGN KEY([UpdatedBy])
REFERENCES [dbo].[aspnet_Users] ([UserId])
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_UpdatedByUser]
GO

ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [CK_Email_Person_Or_Institution] CHECK  (([PersonId] IS NOT NULL AND [InstitutionId] IS NULL OR [PersonId] IS NULL AND [InstitutionId] IS NOT NULL))
GO

ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [CK_Email_Person_Or_Institution]
GO
我被带到这个项目是因为它已经过了初始阶段 并且已经投入生产,并且存在性能问题

您没有说明这些性能问题是什么,因此我将仅限于外键

当我看DB图时,它看起来像一条100车道的高速公路 由于CreatedBy、CreatedByProxy、, UpdatedBy,UpdatedBy代理外键

当我看到这样的列时,我必须询问它们是否包含关于业务实体的信息——在本例中是一个人的电子邮件地址——或者关于该实体所在行的信息

它们似乎包含有关该行的信息。(但我可能错了。)

如果它们确实包含关于行的信息,并且在大多数查询中不需要它们,则可以将它们移动到另一个表中。如果移动它们,则在将行插入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语句的表中SELECT语句的性能。(行数越窄;每页行数越多。)


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

GUID
列上使用集群主键肯定会破坏性能。这将导致大量索引碎片,并可能导致操作中出现大量页面拆分,从而导致最终性能损失,但OP没有在GUID上创建群集主键。OP在一个表中的GUID上有一个非聚集主键,在另一个表中的电子邮件上有一个聚集主键。