2013-08-28 79 views
4

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

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

请不要误解我的意思,我知道为什么外键与指定DB上表的关系有关。但是,这似乎只是仪式而非实际相关,特别是当我的交易变得越来越慢时。

问题:

1.是否值得失去力图保持正式指定,即使它不是必要的关系有些表现?

2.有什么办法可以加快我的交易,仍然保持FOREIGN KEY规范。

谢谢。

REPLIES

这里是如何的表创建。

创建表的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 

SOLUTION

我所做的外键列的索引。现在我的查询又快了。

Create nonclustered index IX_RelatedTableA 
on RelatedTableA (ID) 
GO 
+1

“这不是必要的”是什么意思?要么你想要数据完整性,要么你不需要。 –

+0

这只是我的看法,因为我的程序在没有它的情况下运行得更快。这可能是我在其他地方犯了一个错误。这就是我寻求帮助的原因。 – davidXYZ

回答

4

如果外键列索引正确(应与申报自动发生,我相信),那么你应该看到在最坏的情况小的性能损失。请列出每个表的CREATE TABLE SQL,因为它听起来像是有错误的地方。

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

使用外键关系的目的不是为了“正式宣布”任何(或不只是要做到这一点,在任何情况下)。相反,它会向数据库引擎提供足够的信息,以便执行数据的完整性。这意味着您不能错误地让您的应用程序添加或删除记录,以致违反了关系。另外,使用数据库的其他应用程序(例如Management Studio)也不能这样做。正是出于这个原因 - 保证数据库引擎执行规则 - 声明约束非常重要。

+0

我在问题中添加了CREATE SQL。请看一下。 – davidXYZ

+1

好吧,刚刚检查了一些关于Stack Overflow的其他问题,我错了 - 那些外键列是*不*自动索引的。你必须在它们上创建索引。我正在更新我的答案。 –

+0

不知道我是如何得到这个错误的,但你可以打赌我要回去检查一些数据库。 。 。 (我猜一些数据库图表工具创建索引)。 –

1

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

顺便说一句,与维持数据完整性(这是巨大的)相比,FK具有更多的价值。如果您打算开始使用ORM(例如实体框架),那么使用FK将使您的生活变得更加轻松。

+0

在从X删除前,我从A,B,C,D中删除。前4个DELETE仍以正常速度运行,但最后一个在外键分配后变慢。删除发生在Java内部。我会研究DELETE CASCADE选项,尽管这看起来不像解决时间问题。 – davidXYZ