2012-03-13 4 views
0

Приведенный ниже код C# выполняется через 3 секунды. Я также перечислил вывод SQL Profiler. Если я изменю инструкцию, чтобы не использовать Dynamic SQL, она выполняется в миллисекундах. Я не могу найти никаких хороших ресурсов для решения этой проблемы. Но мне удалось найти статью, объясняющую, что в Dynamic SQL, поскольку парсер не знает значения параметров, он не может оптимизировать план запроса.Как я могу исправить проблему с производительностью этого запроса linq?

public string GetIncorporation(Parcel parcel) 
    { 

    var result = (from c in _context.Districts 
        where c.PARCEL_ID == parcel.PARCEL_ID && c.DB_YEAR == parcel.DB_YEAR && c.DISTRICT_CD.CompareTo("9000") < 0 
        select c).ToList(); 

exec sp_executesql N'SELECT 
[GroupBy1].[A1] AS [C1] 
FROM (SELECT 
    MAX([Filter1].[A1]) AS [A1] 
    FROM (SELECT 
     SUBSTRING([Extent1].[DISTRICT_CD], 0 + 1, 2) + N''00'' AS [A1] 
     FROM [STAGE].[DISTRICT] AS [Extent1] 
     WHERE ([Extent1].[PARCEL_ID] = @p__linq__0) AND ([Extent1].[DB_YEAR] = @p__linq__1) AND ([Extent1].[DISTRICT_CD] < N''9000'') 
    ) AS [Filter1] 
) AS [GroupBy1]',N'@p__linq__0 nvarchar(4000),@p__linq__1 int',@p__linq__0=N'0001-02-0003',@p__linq__1=2012 

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

ответ

4

Вы вставляете этот запрос в SSMS, запускаете план выполнения и видите ли он какие-либо недостающие индексы?

Кроме того, если вам не нужны все столбцы из таблицы, ограничить их с помощью отборного:

var result = (from c in _context.Districts 
        where c.PARCEL_ID == parcel.PARCEL_ID && c.DB_YEAR == parcel.DB_YEAR && c.DISTRICT_CD.CompareTo("9000") < 0 
        select c.Parcel_ID).ToList(); 

или

var result = (from c in _context.Districts 
        where c.PARCEL_ID == parcel.PARCEL_ID && c.DB_YEAR == parcel.DB_YEAR && c.DISTRICT_CD.CompareTo("9000") < 0 
        select new { c.Parcel_ID, c.column2, c.column3}).ToList(); 
+0

Да, я сделал это. Он предлагает создать индекс на DB_YEAR, включая PARCEL_ID, DISTRICT_CD –

+0

Дело в том, что ... У меня уже есть индекс PARCEL_ID, DB_YEAR, DISTRICT_CD. Используется версией динамического запроса t-sql. –

0

LINQ выглядит хорошо, ты получил правильные индексы?

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

0

Ваша проблема с производительностью в части «CompareTo». Эта функция не может быть переведена на обычный SQL, поэтому инфраструктура Entity сначала материализует все объекты, соответствующие первым двум условиям (взятым с чистым SQL). После этого (whitch занимает некоторое время, как вы можете видеть), третье условие сопоставляется в памяти. Избегайте метода CompareTo в вашем запросе linq, и ваши проблемы исчезнут.

+0

Вы ошиблись. Но вы указали на ошибку в моем вопросе. Я вставил неправильный sql. Странно, что движок linq делает идеальную работу по преобразованию CompareTo() в инструкцию SQL. –

+0

BTW Я думаю, что это УДИВИТЕЛЬНО! что linq может сделать такое преобразование! Я предположил, что это сработает, как вы предложили. –