Linq запрос занимает слишком много времени - PullRequest
5 голосов
/ 25 августа 2011

Интересно, может ли кто-нибудь помочь мне с этим?У меня есть запрос LINQ - нет проблем с ним, но он возвращает слишком много времени

var result = Context.paf_wgs84.Where(c => c.Postcode.Contains(postcode)).Take(15);

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

Проблема в том, что существует 1,6 миллиона записей

Выполнение следующего кода в Management Studio занимает около 3 секунд

SELECT   code
FROM     paf_wgs84
WHERE    (code LIKE '%EC1%')

, тогда как при выполнении следующего кода требуетсяменее секунды

SELECT   TOP 15  code
FROM     paf_wgs84
WHERE    (code LIKE '%EC1%')

Есть ли способ сделать что-то подобное в LINQ без использования .take()?

Ответы [ 4 ]

2 голосов
/ 25 августа 2011

Вы можете попробовать что-то вроде этого.Это вернет только один столбец.

var result = Context.paf_wgs84.Where(c => c.Postcode.Contains(postcode)).Select(x=>new {x.Postcode}).Take(15);

Сгенерированный оператор Sql будет выглядеть следующим образом.

/*
-- Region Parameters
DECLARE @p0 VarChar(1000) = '%s%'
-- EndRegion
SELECT TOP (15) [t0].[code]
FROM [paf_wgs84] AS [t0]
WHERE [t0].[code] LIKE @p0
*/
1 голос
/ 25 августа 2011

проблема может заключаться в том, что ваш метод содержит в statemnt, что он не сопоставляется с оператором like в sql, и вы в конечном итоге получаете все строки в sql, а затем делаете поиск в вашем веб-уровне вместо того, чтобы делать то же самое в вашей БД.

Используйте SqlMethods для того же .. somethig следующим образом:

SqlMethods.Like(c.Postcode, string.Format("%{0}%",postcode));

иногда вы также можете использовать строковые методы, такие как: String.StartsWith или String.Ends with, но в этом вы не можете ..

Также - предложения LIKE, начинающиеся с%, редко бывают хорошей идеей - не в последнюю очередь, они не могут эффективно использовать какой-либо индекс. Вы могли бы иметь лучшую производительность, используя «полнотекстовый поиск»; но это не доступно напрямую через LINQ

надеюсь, что это поможет вашей проблеме.

0 голосов
/ 21 апреля 2012

Производительность этих типов запросов была значительно улучшена в SQL Server 2012 с использованием новых операторов FETCH и OFFSET (хотя я до сих пор не видел много сравнительных данных ...).

Проблема в том, что EF еще не использует эти новые функции.

Возможное решение - использовать SQL Server 2012 и написать sproc с помощью FETCH / OFFSET, а затем нацелиться на него с помощью EF.Определенно, это не краткосрочное решение, но я хотел бы указать на этот вариант.

0 голосов
/ 25 августа 2011

Я изменил выражение на

var result = Context.paf_wgs84.Where(c => c.Postcode.StartsWith(postcode)).Take(10).Select(c => c.Postcode).ToArray();

Я использовал внешний вид foreach для добавления в массив строк - я думаю, что именно здесь я терял время!

Спасибо за помощь всем.

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