2014-01-09 46 views
0

我有這樣定義的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)) 

性能查詢使用名稱字段包含和FREETEXT效果很好。

但是,我試圖保持我的名稱列的值獨一無二。在名稱列中搜索現有條目對於大量名稱(通常是批量爲1,000)來說速度慢得令人難以置信,即使在名稱字段上有一個索引。查詢計劃表明我正在按預期使用索引。

要搜索現有價值,我的查詢看起來是這樣的:

SELECT TOP 1 Id, Name from Search_Name where Name = 'My Name Value' 

我已經試過名稱列複製到另一列和新列搜索,但最終的效果是一樣的。

在這一點上,我想我一定是誤用這個功能。

我應該停止嘗試防止重複嗎?我正在使用鏈接表將這些搜索名稱值連接到基礎數據。它似乎有點'骯髒',只是存儲一堆重複值...

...或者有更快的方式來獲取1,000名稱的名單,看看哪些已經存儲在數據庫中?

+0

您是否在設定操作中檢查了1000個名稱,例如一個INNER JOIN與一個潛在的名稱表,或從一個應用程序進行1000次往返?還是其他一些技巧?爲什麼要檢查,即避免使用唯一索引失敗的INSERT?如果是這樣,帶有OUTPUT子句的MERGE可以讓您執行批量INSERT並通知任何被拒絕的名稱。 – HABO

+0

@HABO我的客戶端應用程序具有列表中的值,並且正在爲每個條目重複上述選擇語句,所以我使用'1,000往返'方法。我的潛在解決方法之一是試圖插入全部,但讓一個唯一索引失敗單個插入。 SqlBulkCopy似乎不是一個選項,因爲整個操作在第一次失敗的INSERT時將失敗。 –

+0

要做的第一個更改是將整個列表一次性傳送到SQL Server。無論您是執行INSERT ... SELECT ... LEFT OUTER JOIN,只插入沒有重複項或MERGE以完成相同目標的行,將它作爲集合操作將會在性能上產生很大的差異。將列表作爲表值參數(TVP)傳遞是一種乾淨的方式來處理它。看看[這裏](http://blog.sqlauthority.com/2008/08/31/sql-server-table-valued-parameters-in-sql-server-2008/)爲例。您仍然可以使用OUTPUT子句來跟蹤哪些行進行了剪切或沒有剪切。 – HABO

回答

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語句和OUTPUT添加的名字,那些間沒有」噸,或兩者兼而有之。

相關問題