.NET против SQL Server — лучшая практика для повторного поиска

#asp.net #.net #sql-server #sql-server-2005

#asp.net #.net #sql-server #sql-server-2005

Вопрос:

Мой клиент запрашивает добавление поиска на основе «предложения» в определенное поле формы. Другими словами, когда вы начинаете вводить текст в поле, должно появиться всплывающее окно «Стиль Google», в котором предлагаются возможные результаты для выбора. Возможных предложений будет порядка «десятков тысяч» — это наилучшая оценка, которую я имею в настоящее время по количеству.

Используя AJAX для отправки / получения результата, мой вопрос заключается в том, лучше ли хранить ВСЕ предложения внутри.ЧИСТЫЙ кэш и обработка там, или лучше запускать запрос на основе хранимых процедур на SQL Server для каждого запроса?

Это будет использовать .NET 2.0 и SQL Server 2005

Ответ №1:

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

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

Комментарии:

1. Мне очень нравится эта идея, и я обязательно включу ее в свой дизайн… Спасибо

2. это отличный момент… И чем больше я думаю об этом, как пользователь поиска в Google, я в конечном итоге инстинктивно создаю паузу при вводе сейчас. Я быстро введу то, что считаю «достаточно», а затем сделаю небольшую паузу, чтобы посмотреть, «дошло ли оно». Чувствуйте себя дураком, вводя в поле поиска без подсказки, хотя 🙂

Ответ №2:

Ваше бутылочное горлышко будет передавать данные с сервера в браузер. Вы можете легко получить большой результат из базы данных практически в кратчайшие сроки, но возврат к браузеру занимает целую вечность.

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

Когда объем трафика данных снизится до разумного уровня, вы можете приступить к оптимизации серверной части. С некоторым кэшированием и логикой это должно быть легко, учитывая, что при вводе пользователем результат часто является подмножеством предыдущего результата, например, совпадение для «hat» является подмножеством совпадения для «ha».

Комментарии:

1. Я думаю, вы попали в большую проблему… в частности, когда люди ищут регулярно повторяющееся слово в списке предложений. Хотя идея кэширования, которую вы предлагаете, повысит удобство работы пользователей, для КАЖДОГО пользователя на веб-сайте потребуется кэш, что может еще больше увеличить требования к ресурсам сервера.

2. @freefaller: для этого не потребуется кэш для каждого пользователя, он может просто использовать преимущества того, как запросы часто следуют друг за другом. Например, можно использовать кэшированный результат для «ha» для получения результата для «hat» без необходимости запрашивать базу данных.

3. извините, я, должно быть, что-то упускаю, потому что я не вижу, как это может быть иначе, чем для конкретного пользователя. Если на сайте одновременно находятся несколько пользователей (на что я надеюсь), тогда было бы невозможно использовать подмножество, поскольку запрос, скорее всего, будет совершенно другим.

4. @freefaller: нет причин делать его специфичным для пользователя. Большую часть времени кэш будет использовать предыдущий результат от того же пользователя, но если другой пользователь ищет что-то похожее, пока результат все еще находится в кэше, нет причин не использовать его. Рассмотрим, например, что результат для «ca» можно использовать как для получения результата для «car», так и для «cat».

5. Я понимаю, что вы говорите, и да, я полагаю, имеет смысл попытаться сохранить (даже в течение короткого промежутка времени) этот подмножество. Спасибо за ваш вклад

Ответ №3:

Когда я видел поиск типа «предлагать при вводе», выполняемый в средах SQL Server, я видел лучшую производительность при использовании какого-либо механизма кэширования и, как правило, распределенного подхода — как правило, memcached. Даже если ваш код хорошо оптимизирован, ваша база данных настроена хорошо, и ваш запрос занимает всего <= 10 мс с вызовом, обработкой и возвратом, то есть по-прежнему 10 мс при вводе.

Комментарии:

1. Спасибо, Майк. Немного неясно, говорите ли вы, что ответ в 10 мс — это хорошо или плохо. Я лично не видел бы проблемы с чем-либо под (скажем) ответом в 500 мс, поскольку мгновенность не совсем критична

2. Я говорил, что было бы здорово меньше 10 мс, но я использовал это число, чтобы понять, что даже высокая производительность СУБД, вызываемой через стек, иногда может показаться вялой пользователям, выполняющим поиск по типу поиска. 10 мс, вероятно, были неправильной продолжительностью для злоупотребления в моем примере, но я хочу сказать, что я думаю, что вы получите более быстрые предложения при использовании подхода к кешированию. Я не думаю, что переход на SP и оптимизация базы данных / вызовов для этой цели будут ужасными, просто не такими быстрыми.

Ответ №4:

Это зависит от количества элементов. Если вы можете кэшировать элементы в процессе .NET без нехватки памяти, это, безусловно, будет быстрее.

Но если это невозможно сделать, вы застряли с доступом к базе данных при каждом запросе. Хранимая процедура была бы хорошим способом сделать это.

Но есть некоторые шаблоны проектирования, которые могут помочь вам. Я использовал следующие два при разработке чего-то похожего на то, что вы делаете.

Комментарии:

1. Спасибо, Ваутер — это в значительной степени именно те шаблоны мышления, через которые я проходил. Эти два варианта, безусловно, стоит рассмотреть, но я бы беспокоился о возможном количестве данных для загрузки и хранения в браузере.

2. В приложении «динамический поиск», которое я написал, мы ограничили максимальное количество отображаемых элементов примерно до 10. Таким образом, для каждого нажатия клавиши мы кэшировали бы 10 элементов, и когда пользователь вводил больше символов, мы могли бы фильтровать список еще больше.