2012-03-11 1 views
1

я нашел много учебников и книг, которые реализует автозаполнения поиска в веб-приложениях MVC как в: -Как масштабируемой использует .Contains для поиска и автоматического завершения поиска в asp.net веб-приложений 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

+0

Почему бы вам просто не проверить его на больших наборах данных? –

+1

Зависит от вашей схемы и количества данных. Для больших наборов данных я, вероятно, попал бы в кеш вместо базы данных. –

ответ

6

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

Чтобы выбрать ваш запрос, вы можете ознакомиться с возможностями полнотекстового индексирования, подробнее здесь: SQL Server: how to optimize "like" queries?).

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

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

0

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

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

0

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

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

1

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

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