主键重复记录绕过下一个插入

uir*_*irn 4 sql-server primary-key

奇怪的问题.我在表中插入10,000条记录,主键不是标识字段.所以当插入所有10,000,如果有些是重复的,有没有办法跳转到sql server插入中的下一条记录,并确保非重复进入?我真的不在乎重复没有插入.

Gal*_*llo 8

使用"忽略重复键"选项.

最简单的方法是删除SQL Server Management Studio中的主键.

然后创建一个类型为"Index"的新索引,将Is Unique设置为"Yes",并将"Ignore Duplicate Keys"设置为"Yes".然后插入您的记录.除了重复之外,它会将它们全部插入.完成后,您可以删除此索引,然后重新创建主键.

如果需要TSQL方法,请参阅CREATE INDEX调用中的IGNORE_DUP_KEY选项:

CREATE INDEX(Transact-SQL)

编辑:

另一种方法是在源表和要插入的记录之间使用LEFT JOIN,以及GROUP BY子句,只插入源中不存在的记录.GROUP BY将消除新记录中的重复项.


A-K*_*A-K 5

您需要定义主键以忽略重复项:

CREATE TABLE [dbo].[t2](
      [n] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
      [n] ASC
)WITH (IGNORE_DUP_KEY = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)

使用此选项可能会影响性能:

如果您的数据具有较小百分比的重复项,那么IGNORE_DUP_KEY可能会加快您的插入速度.对于大量重复项,IGNORE_DUP_KEY可能会显着降低它们的速度.我设置了两个表,删除了所有不相关的细节,如下所示:

CREATE TABLE t1(n INT NOT NULL PRIMARY KEY)
GO
CREATE TABLE [dbo].[t2](
      [n] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
      [n] ASC
)WITH (IGNORE_DUP_KEY = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)

如果传入的数据没有重复,则两个插入的性能始终相同:

INSERT t1(n)
SELECT n FROM dbo.Numbers

INSERT t2(n)
SELECT n FROM dbo.Numbers
Run Code Online (Sandbox Code Playgroud)

(注意dbo.数字有100万行.)当然,我总是在测试之间截断两个表.

如果传入的数据具有1%的重复项,则IGNORE_DUP_KEY的插入执行速度始终大约快5%:

INSERT t1(n)
SELECT DISTINCT n FROM(
SELECT n FROM dbo.Numbers
UNION ALL
SELECT n FROM dbo.Numbers WHERE n <10000
) AS t

INSERT t2(n)
SELECT n FROM dbo.Numbers
UNION ALL
SELECT n FROM dbo.Numbers WHERE n <10000
Run Code Online (Sandbox Code Playgroud)

另一方面,如果传入数据具有100%的重复数据,则IGNORE_DUP_KEY的插入一致地执行至少300%的速度,对于大量的200万行:

INSERT t1(n)
SELECT DISTINCT n FROM(
SELECT n FROM dbo.Numbers
UNION ALL
SELECT n FROM dbo.Numbers
) AS t

INSERT t2(n)
SELECT n FROM dbo.Numbers
UNION ALL
SELECT n FROM dbo.Numbers
Run Code Online (Sandbox Code Playgroud)

以及一组较小的200K行:

INSERT t1(n)
SELECT DISTINCT n FROM(
SELECT n FROM dbo.Numbers WHERE n<100000
UNION ALL
SELECT n FROM dbo.Numbers WHERE n<100000
) AS t

INSERT t2(n)
SELECT n FROM dbo.Numbers WHERE n<100000
UNION ALL
SELECT n FROM dbo.Numbers WHERE n<100000 
Run Code Online (Sandbox Code Playgroud)

总的来说,我决定在我的特定情况下不使用IGNORE_DUP_KEY.我认为少量重复项的小额节省并不能证明大量重复数据会导致性能大幅下降的风险.