繁体   English   中英

返回主键值SQL Server 2005的最快方法

[英]Fastest way to return a primary key value SQL Server 2005

我有一个两列表,主键(int)和唯一值(nvarchar(255))

当我向该表插入一个值时,我可以使用Scope_identity()返回刚刚插入的值的主键。 但是,如果值已经存在,我必须执行另外的选择以返回主键以进行后续操作(将该主键插入第二个表)

我认为必须有一个更好的方法来做到这一点 - 我考虑使用覆盖索引,但表只有两列,我读到的覆盖索引的大部分内容表明它们只有在表明显大于索引的情况下才有用。

有没有更快的方法来做到这一点? 覆盖的索引是否会更快,即使它与表的大小相同?

构建索引不会获得任何东西,因为您已经将值列创建为唯一(在后台构建索引)。 实际上,全表扫描与您的方案中的索引扫描没有什么不同。

我假设你想要有一种插入 - 如果不是已存在的行为。 没有办法绕过第二个选择

if not exists (select ID from where name = @...)
   insert into ...
   select SCOPE_IDENTITY()
else 
   (select ID from where name = @...)

如果该值恰好存在,则查询通常会被缓存,因此第二个ID select的性能不会受到影响。

为第二个条目创建唯一索引,然后:

if not exists (select null from ...)
   insert into ...
else 
   select x from ...

你无法摆脱索引,并没有太大的开销 - SQL服务器支持最多900字节的索引列,并且没有区别对待。

模型的需求比任何感知的性能问题更重要,象征字符串(这是你正在做的)是减少数据库大小的常用方法,这间接(通常)意味着更好的性能。

- 编辑 -

安抚蒂莫西:

declare @x int = select x from ...

if (@x is not null)
   return x 
else
   ...
[Update statment here]
IF (@@ROWCOUNT = 0)
BEGIN
  [Insert statment here]
  SELECT Scope_Identity()
END
ELSE
BEGIN
  [SELECT id statment here]
END

我不知道性能,但它没有很大的开销

正如已经提到的,这实际上不应该是一个缓慢的操作,特别是如果你索引两个列。 但是,如果您决定减少此操作的费用,那么我认为没有理由不能完全删除表,只是直接使用唯一值而不是在此表中查找它。 像这样的1-1映射(理论上)是多余的。 我在理论上说,因为使用nvarchar而不是int可能会影响性能。

我会发布这个答案,因为其他人似乎都说你必须在记录存在的情况下两次查询表...那不是真的。

步骤1)在另一列上创建唯一索引:

我推荐这个作为索引:

- 我们包含“ID”列,以便在“WHERE”子句完成后SQL不必查看。

CREATE INDEX MyLilIndex ON dbo.MyTable (Column2) INCLUDE (ID)

第2步)

DECLARE @TheID INT
SELECT @TheID = ID from MyTable WHERE Column2 = 'blah blah'

IF (@TheID IS NOT NULL)
BEGIN
    -- See, you don't have to query the table twice!
    SELECT @TheID AS TheIDYouWanted
END
ELSE
    INSERT...
    SELECT SCOPE_IDENTITY() AS TheIDYouWanted

您可以使用OUTPUT子句在同一语句中返回值。 这是一个例子。

DDL:

CREATE TABLE ##t (
    id int PRIMARY KEY IDENTITY(1,1),
    val varchar(255) NOT NULL
)
GO

-- no need for INCLUDE as PK column is always included in the index
CREATE UNIQUE INDEX AK_t_val ON ##t (val)

DML:

DECLARE @id int, @val varchar(255)

SET @val = 'test' -- or whatever you need here

SELECT @id = id FROM ##t WHERE val = @val

IF (@id IS NULL)
BEGIN
    DECLARE @new TABLE (id int)

    INSERT INTO ##t (val) 
    OUTPUT inserted.id INTO @new -- put new ID into table variable immediately
    VALUES (@val)

    SELECT @id = id FROM @new
END

PRINT @id

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM