我有一个像这样定义的SQL 2008 R2表:
CREATE TABLE [dbo].[Search_Name](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](300) NULL),
CONSTRAINT [PK_Search_Name] PRIMARY KEY CLUSTERED ([Id] ASC))
使用CONTAINS和FREETEXT查询Name字段的性能运行良好。
但是,我正在尝试保持“名称”列的值唯一。对于大量名称(通常是1,000个批次),即使在“名称”字段上有索引,在“名称”列中搜索现有条目的速度也令人难以置信。查询计划表明我正在按预期使用索引。
要搜索现有值,我的查询如下所示:
SELECT TOP 1 Id, Name from Search_Name where Name = 'My Name Value'
我尝试将Name列重复到另一列并搜索新列,但净效果是相同的。
此时,我想我一定是误用了这个功能。
我应该停止尝试防止重复吗?我正在使用链接表将这些搜索名称值连接到基础数据。仅仅存储一大堆重复值似乎“脏”......
...或者是否有更快的方法来获取1,000个名称的列表并查看哪些名称已存储在数据库中?
答案 0 :(得分:1)
要做的第一个更改是一次将整个列表添加到SQL Server。无论您如何将名称添加到现有表中,将其作为集合操作进行操作都会对性能产生很大影响。
将List作为表值参数(TVP)传递是一种干净的方法来处理它。看看here的例子。您仍然可以使用OUTPUT子句来跟踪哪些行执行或不执行剪切,例如:
-- Some sample existing names.
declare @Search_Name as Table ( Id Int Identity, Name VarChar(32) );
insert into @Search_Name ( Name ) values ( 'Bob' ), ( 'Carol' ), ( 'Ted' ), ( 'Alice' );
select * from @Search_Name;
-- Some (prospective) new names.
declare @New_Names as Table ( Name VarChar(32) );
insert into @New_Names ( Name ) values ( 'Ralph' ), ( 'Alice' ), ( 'Ed' ), ( 'Trixie' );
select * from @New_Names;
-- Add the unique new names.
declare @Inserted as Table ( Id Int, Name VarChar(32) );
insert into @Search_Name
output inserted.Id, inserted.Name into @Inserted
select New.Name
from @New_Names as New left outer join
@Search_Name as Old on Old.Name = New.Name
where Old.Id is NULL;
-- Results.
select * from @Search_Name;
-- The names that were added and their id's.
select * from @Inserted;
-- The names that were not added.
select New.Name
from @New_Names as New left outer join
@Inserted as I on I.Name = New.Name
where I.Id is NULL;
或者,您可以使用MERGE语句并输出已添加的名称,未添加的名称或两者。