Обычно начинаются с базы данных Adventure Works для таких примеров. Я буду говорить о точных совпадениях с рычагом поиска индекса, точными совпадениями, которые используют сканирование индекса, и полной индексацией текста, в которой вы можете выполнить точное совпадение, приводящее к поиску.
Таблица Person.Person имеет как последнее, так и первое имя, например, ваш пример. Я сохраняю только первичный ключ для идентификатора бизнеса и создаю один индекс (последний, первый).
--
-- Just PK & One index for test
--
-- Sample database
use [AdventureWorks2012];
go
-- add the index
CREATE NONCLUSTERED INDEX [IX_Person_LastName_FirstName] ON [Person].[Person]
(
[LastName] ASC,
[FirstName] ASC
);
go
Запуск с дикой картой для неточного соответствия. Выполнить с помощью только текста для точного соответствия. Я случайно выбрал два имени из таблицы Person.Person.
--
-- Run for match type
--
-- Sample database
use [AdventureWorks2012];
go
-- remove temp table
drop table #inquiry;
go
-- A table with first, last name combos to search
create table #inquiry
(
first_name varchar(50),
last_name varchar(50)
);
go
-- Add two person.person names
insert into #inquiry values
('%Cristian%', '%Petculescu%'),
('%John%', '%Kane%');
/*
('Cristian', 'Petculescu'),
('John', 'Kane');
*/
go
-- Show search values
select * from #inquiry;
go
Следующий шаг при проверке времени выполнения - очистить кэш процедур и буферы памяти. Вы не хотите, чтобы существующие планы или данные искажали цифры.
-- Remove clean buffers & clear plan cache
CHECKPOINT
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
GO
-- Show time & i/o
SET STATISTICS TIME ON
SET STATISTICS IO ON
GO
Первый оператор SQL будет выполнять внутреннее соединение между таблицей временных значений поиска и Person.Person.
-- Exact match
select *
from
[Person].[Person] p join #inquiry i
on p.FirstName = i.first_name and p.LastName = i.last_name
Статистика и время выполнения.
Таблица «Человек». Число сканирования 2, логическое чтение 16, физические чтения 8, время процессора = 0 мс, прошедшее время = 29 мс.
В результате плана запроса выполняется сканирование таблицы #inquiry и индексный указатель индекса на последнее и первое имя. Это хороший простой план.
Позволяет повторить это с неточным матчем с использованием диких карт и LIKE оператором.
-- In-Exact match
select *
from
[Person].[Person] p join #inquiry i
on p.FirstName like i.first_name and p.LastName like i.last_name
Статистика и время выполнения.
Таблица «Человек». Число сканирования 2, логическое чтение 219, время процессора = 32 мс, прошедшее время = 58 мс.
Результирующий план запроса намного сложнее. Мы по-прежнему выполняем сканирование таблицы #inquiry, так как оно не имеет индекса. Тем не менее, есть много вложенных объединений, которые используют индекс с беспристрастным соответствием.
Мы добавили еще три оператора в запрос, а время выполнения в два раза больше, чем точное совпадение.
Короче говоря, если вы делаете неточные матчи с LIKE команды, они будут более дорогими.
Если вы ищете сотни тысяч записей, используйте FULL TEXT INDEX (FTI). Я написал две статьи по этой теме.
http://craftydba.com/?p=1421 http://craftydba.com/?p=1629
Каждую ночь, вы будете иметь процесс, который обновляет ИУП с любыми изменениями. После этого вы можете использовать оператор CONTAINS(), чтобы использовать индекс в нечетких совпадениях.
Надеюсь, я объяснил различия. Я видел постоянную путаницу в этой теме, и я хотел кое-что рассказать о переполнении стека, о котором я мог бы обратиться.
Удачи Хуан.
Вы вообще не объяснили «петлю» –
Ваш вопрос непонятен. –