title: Foreign Key Relationship possible performance issues
body: <p>We have a <code>User</code> table with a <code>GUID</code> aka <code>uniqueidentifier</code> as the <code>PK</code>. Nearly every other table in the database ties back to this table with <strong>4</strong> <code>FK</code> references. When I look at the <code>DB</code> diagram it looks like a 100 lane highway coming out of the <code>User</code> table because of the <code>CreatedBy</code>, <code>CreatedByProxy</code>, <code>UpdatedBy</code>, <code>UpdatedByProxy</code> foreign keys. </p>
  
  <p>I was brought onto this project after it was already past inception and in production already, and with performance issues.</p>
  
  <p>I was wondering if this <code>DB</code> pattern will cause major growing pains when the user list starts to grow. Are we going to run into more performance issues in the future because of this, or if we create an index will keeping the foreign keys cause the indexes to be huge. I just don't remember a website that I've worked on before that had the foreign keys to this extent before, and I'm worried about future proofing/fixing it. I'm really just trying to justify whether or not to keep or remove the foreign keys or modify the structure so that</p>
  
  <p><strong>User Table:</strong></p>
  
  <pre><code>    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]
  </code></pre>
  
  <p><strong>One other Table that references User:</strong></p>
  
  <pre><code>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
  </code></pre>