SQL Server и производительность для динамического поиска

Мне было интересно, какие были лучшие методы для создания запроса в sql с динамическим значением, скажем, у меня есть значение (nvarchar (max))

Значение: "912345678"

select * from AllData
where Number like '%912345678%' 

значение: "Майкл"

select * from AllData
where Name like '%Michael%' 

Значение: "Улица номер 10"

select * from AllData
where Address like '%Street number 10%' 

Этот подход немного медленнее, так как поиск числа, имеющего 9 цифр, будет быстрее без%, как этот

select * from AllData
where Number like '912345678' 

Я использую EDMX для подключения к внешней базе данных на С#, например:

var Result = EDMXEntity.Entities.Where(x => 
(SqlFunctions.PatIndex("%" + Value.ToLower() +"%", x.Name.ToString().ToLower()) > 0) 
|| (SqlFunctions.PatIndex("%" + Value.ToLower() +"%", x.Number.ToString().ToLower()) > 0)
|| (SqlFunctions.PatIndex("%" + Value.ToLower() +"%", x.Address.ToString().ToLower()) > 0)).Take(50).ToList();

Как повысить производительность?

Ответы

Ответ 1

Подстановочные запросы, подобные этим в полях varchar/nvarchar, собираются перебирать каждый символ, более или менее, для записей, соответствующих критериям.

Отличная (и быстрая!) опция для таких видов поиска:

  • Создайте полнотекстовый каталог для хранения полнотекстовых индексов.
  • Поместите полнотекстовый индекс в столбцы в каждой таблице, которые нужно искать.
  • Используйте ключевое слово CONTAINS при поиске, а не в виде подстановочных знаков.

Вы упомянули о том, что искали достоверные источники, здесь является хорошим показанием.

Ответ 2

Если использование LIKE и PATINDEX не принесло вам необходимой производительности, вы, вероятно, должны написать sp, который будет использовать FTS.

Ответ 3

Для поиска с помощью "like" в EF вы можете использовать Содержит():

var Result = EDMXEntity.Entities.Where(
x => x.Name.Contains(Value) ||
x => x.Number.ToString().Contains(Value) ||
x => x.Address.Contains(Value)).Take(50).ToList();

Но при таком поиске вы никогда не добьетесь хорошей производительности. Вам нужно изменить способ поиска или хранения данных в БД. Например, если вы уверены, что пользователь ищет имя, вы можете искать только в столбце "name".