外键减速删除

时间:2013-08-28 20:02:57

标签: sql sql-server database foreign-keys primary-key

我有一个表X,它有一个自动递增的ID列作为其主键。我有其他表A,B,C和D来补充表X中的信息。每个表都必须包含一个引用表X中的ID的列。我已经完成了这个并且在我的代码(Java)中我有一个将每个条目的ID返回到表X并在插入其他表时使用它的方法。一切都运作良好。

现在,我被建议将表A,B,C和D上的ID列分配为FOREIGN KEYS因为“这是正确的事情”。我做到了现在删除表X中的行需要花费大量时间才能完成。插入其他表也需要更长的时间。

请不要误解我的意思,我知道为什么外键与指定数据库中表的关系有关。但它开始似乎只是仪式而不是实际相关,特别是因为我的交易变得越来越慢。

问题:

1。是否值得为了保持关系正式指定而失去一些表现,即使它不是必要的?

2。有什么办法可以加快我的交易速度并保持FOREIGN KEY规格。

感谢。

REPLIES

以下是表格的创建方式。

CREATE Tables SQL:

CREATE TABLE [dbo].[MainTableX](
    [col1] [smalldatetime] ,
    [col2] [varchar] (20) ,
    [ID] [int] IDENTITY(1,1) NOT NULL,
 CONSTRAINT [PK_MainTableX] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)
)
GO


CREATE TABLE [dbo].[RelatedTableA](
    [differentID] [varchar] (50),
    [detail1] [varchar] (40),
    [detail2] [varchar] (40),
 CONSTRAINT [PK_RelatedTableA] PRIMARY KEY CLUSTERED 
(
    [differentID] ASC
)
GO

-- Tables B, C D are pretty much similar to table A

添加外键SQL:

ALTER TABLE RelatedTableA ADD ID INT 
CONSTRAINT fk_refTableX_A FOREIGN KEY (ID)
REFERENCES MainTableX(ID) 
GO
-- Same thing with the other related tables

我将外键列作为索引。现在我的查询又快了。

Create nonclustered index IX_RelatedTableA 
on RelatedTableA (ID) 
GO

2 个答案:

答案 0 :(得分:5)

如果FOREIGN KEY列被正确编入索引(这应该与声明一起自动发生,我相信)那么你应该看到最坏的性能。请列出每个表的CREATE TABLE SQL,因为它听起来像是错误的。

SQL Server不会自动在FK列上创建索引,因此请确保自己执行此操作。

使用FOREIGN KEY关系的目的不是"正式声明"任何事情(或者只是这样做,无论如何)。相反,它为数据库引擎提供了足够的信息,以强制数据的完整性。这意味着您可能会错误地让您的应用程序添加或删除记录,从而违反关系。此外,使用数据库的其他应用程序(例如Management Studio)也不能这样做。出于这个原因 - 保证数据库引擎执行规则 - 声明约束很重要。

答案 1 :(得分:1)

外键不是你的问题。而且你不想删除它们。当您从表X中删除一行时,我假设您首先从表A,B,C和D中删除行?如果你已经建立了FK,你将不得不这样做。你是如何从这些表中删除行的?从Java应用程序中?如果是这样,设置FK以进行级联删除会快得多。这样,您可以进行一次调用以删除表X中的行,并且SQL Server会自动删除所有子行。对于表X中的每次删除,您可以自己保存四次到DB的行程。

顺便说一句,FK的价值不仅仅是维护数据的完整性(这是巨大的)。如果您打算开始使用ORM(例如,实体框架),那么使用FK可以让您的生活更轻松。