Sql server 2008 我的全文索引是否已包含特定值?

Sql server 2008 我的全文索引是否已包含特定值?,sql-server-2008,Sql Server 2008,我有一个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)) SELECT TOP 1 Id, Name from Search_Name where Name

我有一个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))
SELECT TOP 1 Id, Name from Search_Name where Name = 'My Name Value'
使用CONTAINS和FREETEXT查询名称字段的性能良好

但是,我试图保持我的名字列的值唯一。对于大量名称(通常为1000个批次),即使名称字段上有索引,在名称列中搜索现有条目的速度也慢得令人难以置信。查询计划表明我正在按预期使用索引

要搜索现有值,我的查询如下所示:

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))
SELECT TOP 1 Id, Name from Search_Name where Name = 'My Name Value'
我曾尝试将“名称”列复制到另一列,并在新列上搜索,但最终效果相同

在这一点上,我想我一定是误用了这个功能

我应该停止阻止重复吗?我正在使用链接表将这些搜索名称值连接到基础数据。仅仅存储一大堆重复的值似乎有点“脏”


…或者有没有更快的方法来获取1000个名称的列表并查看哪些名称已存储在数据库中?

要做的第一个更改是一次性将整个列表获取到SQL Server。无论如何将名称添加到现有表中,将其作为一个集合操作来执行都将大大提高性能

将列表作为表值参数(TVP)传递是一种干净的处理方法。请看一个例子。您仍然可以使用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语句并输出添加的名称、未添加的名称或两者都输出。

您是在集合操作中检查1000个名称,例如,与预期名称表的内部联接,还是从应用程序执行1000次往返?或者其他技术?为什么要进行检查,即为了避免插入操作因唯一索引而失败?如果是这样,使用带有OUTPUT子句的MERGE可能会让您执行批插入,并通知任何被拒绝的名称。@HABO我的客户端应用程序在列表中有值,并且正在为每个条目重复上述select语句,因此我使用“1000往返”方法。我的一个潜在解决方法是尝试将它们全部插入,但让一个唯一的索引使单个插入失败。SqlBulkCopy似乎不是一个选项,因为整个操作将在第一次失败的插入时失败。要做的第一个更改是一次性将整个列表获取到SQL Server。无论您是否插入。。。选择。。。LEFT OUTER JOIN只插入没有重复项的行,或者合并以实现相同的目的,将其作为一个集合操作来执行将大大提高性能。将列表作为表值参数(TVP)传递是一种干净的处理方法。请看一个例子。您仍然可以使用OUTPUT子句来跟踪哪些行进行了剪切或未进行剪切。@HABO您显然正确地将操作作为一个集合执行,而不是单独执行。我最终的解决方案是使用SqlBulkCopy将数据插入临时表,然后在服务器上进行合并。与我之前的努力相比,它的速度惊人地快!谢谢你给我指明了正确的方向。你愿意回答吗?这样我就可以接受了?