Насколько масштабируется использование .Contains для поиска и автозаполнения поиска в веб-приложениях asp.net MVc - PullRequest
1 голос
/ 12 марта 2012

Я нашел много учебников и книг, в которых реализован автоматический поиск в веб-приложениях MVC, например: -

public ActionResult ArtistSearch(string q)
{
var artists = GetArtists(q);
return PartialView(artists);
}
private List<Artist> GetArtists(string searchString)
{
return storeDB.Artists
.Where(a => a.Name.Contains(searchString))
.ToList();
}

но это подняло вопрос о том, насколько масштабируем этот подход в реальных приложениях, которые могут иметь тысячи записей ???, будет ли использование Contains () хорошо масштабироваться или есть гораздо лучший подход ?? BR

Ответы [ 4 ]

6 голосов
/ 12 марта 2012

Если я правильно помню, string.Contains() переводится в запрос LIKE с подстановочным знаком на каждой стороне строки запроса. Это делает очень трудным / невозможным использование индекса, поэтому вы можете ожидать, что ваша производительность будет равна O (n) в вашем наборе данных, поскольку SQL Server выполняет полное сканирование таблицы (см. Оптимизирует ли SQL Server LIKE ('%%') ) запрос? ).

Чтобы оптимизировать ваш запрос, вы можете взглянуть на возможности полнотекстовой индексации, дополнительную информацию здесь: SQL Server: как оптимизировать «похожие» запросы? ).

Если бы вы могли использовать .StartsWith вместо .Contains, у вас будет запрос LIKE с подстановочным знаком в конце, и вы можете использовать индекс в столбце запроса для быстрого поиска (не забудьте проверить план выполнения запроса !).

Полагаю, производительность будет гораздо лучше восприниматься, если вы попытаетесь сфокусироваться на UX своей функции автозаполнения: запустите поиск автозаполнения после короткого периода блокировки (когда пользователь прекращает вводить текст) и убедитесь, что это не так. не блокировать (происходит в фоновом режиме).

1 голос
/ 12 марта 2012

Это зависит от данных вашей порции.В приложении «реального мира» вам необходимо продумать шум / стоп-слова («и», «the»), сокращения («st» для «улицы») и т. Д. И сложные языки.

Inв этих сценариях .Contains не подходит, и вам нужно будет использовать механизм индексации полнотекстового поиска, например Lucene.NET или полнотекстовый поиск SQL Server.

0 голосов
/ 12 марта 2012

Похоже, вы используете LINQ с Entity Framework.LINQ преобразуется в SQL, а вызов содержимого преобразуется в предложение LIKE WHERE, поэтому вы можете просто запустить SELECT * FROM Artists WHERE Name LIKE '%whatever%', чтобы получить представление о производительности.

Обратите внимание, что есть несколько вещей, которые вы можете сделать дляуменьшить влияние.Один вы можете ограничить количество результатов .Take(20).Также вы можете подождать, пока пользователь не наберет хотя бы пару символов, прежде чем запускать автозаполнение.Наконец, вы можете «уменьшить» вызов автоматического завершения, чтобы не вызывать автоматическое завершение каждый раз, когда они вводят символ, вместо того, чтобы ждать, пока они произойдут, скажем, полсекунды, не вводя дополнительный символ.

0 голосов
/ 12 марта 2012

Запросы подстроки не могут использовать поиск индекса.Но они все еще могут использовать индексы.Сканирование нескольких тысяч записей на самом деле ничего не стоит, если вы не делаете это слишком часто.

Поэтому я рекомендую вам создать индекс для Name, и вы подойдете для огромного количества данных.

...