2014-01-09 4 views
0

Я получил R2 таблицу SQL 2008 определен следующим образом:Имеет ли мой полнотекстовый индекс конкретное значение?

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 работает хорошо.

Тем не менее, я пытаюсь сохранить значения моего имени столбца уникальным. Поиск существующей записи в столбце Имя невероятно медленный для большого количества имен (обычно партий 1000), даже с индексом в поле «Имя». В планах запроса указано, что я использую индекс, как ожидалось.

Для поиска существующего значения, мой запрос выглядит следующим образом:

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

Я пытался дублировать столбец Имя в другой столбец и поиск на новый столбец, но чистый эффект был тот же.

На данный момент я думаю, что я должен неправильно использовать эту функцию.

Должен ли я прекратить попытки предотвратить дублирование? Я использую таблицу ссылок, чтобы объединить эти значения имени поиска в базовые данные. Кажется, что-то «грязно» просто хранить целую кучу повторяющихся значений ...

... или есть более быстрый способ получить список из 1000 имен и посмотреть, какие из них уже хранятся в базе данных?

+0

Вы проверяете 1000 имен в заданной операции, например. INNER JOIN с таблицей предполагаемых имен или путем совершения 1000 обращений от приложения? Или какой-то другой метод? Почему вы проверяете, т. Е. Чтобы избежать INSERT, который потерпит неудачу с уникальным индексом? Если это так, MERGE с предложением OUTPUT может позволить вам сделать пакетный INSERT с уведомлением о любых отклоненных именах. – HABO

+0

@HABO Приложение для клиента имеет значения в списке и повторяет вышеуказанный оператор select для каждой записи, поэтому я использую метод «1,000 round-trip». Один из моих возможных обходных решений заключался в том, чтобы просто вставить их все, но пусть уникальный индекс обрывает отдельные INSERT. 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 за один раз. Независимо от того, как вы добавляете имена в существующую таблицу, выполнение ее как заданной операции будет иметь большое значение в производительности.

Передача списка в качестве параметра таблицы (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 и выдает имена, которые были добавлены, те, которые weren» t или оба.

Смежные вопросы