Работает ли Linq с хранимой процедурой лучше, чем Linq с генерируемым SQL? - PullRequest
2 голосов
/ 30 июня 2011

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

Обычно говорят, что Linq в сети работает медленно.Мой вопрос заключается в том, дают ли Linq с SP лучшую производительность, чем Linq с Generated SQL?или оба одинаковы.

Пожалуйста, руководство.

Ответы [ 2 ]

7 голосов
/ 30 июня 2011

Поскольку Linq-to-Sql использует QueryProvider, который переводит Expression s в операторы SQL, он должен делать это для каждого запроса, выполняемого этим провайдером (если только запрос не был предварительно скомпилирован [подробнее об этом далее)) , Так, например, на базовом уровне:

var people = context.People.Where(p => p.Name == "Matt");

Linq-to-Sql должен преобразовать выражение p => p.Name == "Matt" в дерево выражений, которое, в свою очередь, преобразуется в оператор SQL, что-то похожее на:

SELECT t0.Name FROM People t0 WHERE t0.Name = 'Matt'

Запрос при выполнении на Sql Server, который, в свою очередь, должен сгенерировать план выполнения для запроса и запустить его для таблицы, чтобы получить результаты. Он довольно эффективен при создании правильного запроса для правильной работы и поддерживает более специализированный подход к запросам данных.

В хранимых процедурах Linq-to-Sql не нужно генерировать дерево выражений и из этого генерировать sql, вместо этого сгенерированный классом конструктор обладает всей информацией, необходимой для передачи аргументов из метода в хранимую процедуру ,

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

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

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

public IQueryable<Product> GetProduct(int id)
{
    // Normal query, expression tree and sql generated each time it is
    // it is executed against the data source.
    return context.Products.Where(p => p.Id == id);
}

Принимая во внимание, что скомпилированный запрос:

private static readonly Func<DataContext, int, IQueryable<Product>> ProductById = 
    CompiledQuery.Compile((context, id) => 
        context.Products.Where(p => p.Id == id));

public IQueryable<Product> GetProduct(int id)
{
    return ProductById(context, id);
}

Последний будет использовать предварительно скомпилированный запрос, поэтому он генерирует дерево выражений и sql только один раз.

1 голос
/ 30 июня 2011

Конечно, все зависит от ваших запросов и объема данных, которые вам нужно получить.

Чем сложнее ваши запросы, тем менее эффективным будет SQL, сгенерированный LINQ.

Так что, если ваши запросы очень сложные / тяжелые, я бы предложил использовать хранимые процедуры / представления с тех пор, чтобы вы использовали мощь сервера БД вместо менее эффективного SQL, генерируемого LINQ2SQL.

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