powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
25 сообщений из 72, страница 1 из 3
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755418
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Публикую материалы доклада с SQL Server User Group и пример как оптимизировать доступ к данным ASP.NET приложения с помощью Linq и Entity Framework. http://gandjustas.blogspot.ru/2014/09/asp.net-linq-ef-sql-server-performance.html

Мой блог http://gandjustas.blogspot.ru/ . Много интересного про архитектуру приложений, SharePoint и управление проектами.
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755512
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gandjustas, а если обычный разработчик напишет в хранимой процедуре два запроса (как и с помощью Linq), а не один?
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755590
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAgandjustas, а если обычный разработчик напишет в хранимой процедуре два запроса (как и с помощью Linq), а не один?

Будет тот же эффект. Процедура оптимизируется один раз при первом вызове с учетом фактических параметров. Обойти на уровне SQL можно тремя способами:
1) вызывать процедуру WITH RECOMPILE - самый плохой способ
2) Сделать две процедуры с разными запросами и одну, которая их вызывает, но это дублирование кода будет аццкое
3) клеить строки динамически и использовать sp_executesql - это гемор, ошибки и потенциальные SQL инъекции.

Клеить строки идеальный вариант с точки зрения результата, но без автоматизации типа Linq, крайне сложный.
С Linq (почти) все просто.
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755598
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gandjustasКлеить строки идеальный вариант с точки зрения результата, но без автоматизации типа Linq, крайне сложный .Ну прям-таки крайне сложный. Не преувеличивайте
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755602
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gandjustas3) клеить строки динамически и использовать sp_executesql - это гемор, ошибки и потенциальные SQL инъекции.Всегда так делали. Никакого гемора, никаких инъекций. С точки зрения плана выполнения, результат ничем не отличается от запуска через LINQ.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
-- ...............

if @p is not null
    set @sql = @sql + ' and t.ShippedDate = @p'
else
    set @sql = @sql + ' and t.ShippedDate is null'

exec sp_executesql @sql, '@p datetime', @p
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755614
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,

1) для сортировок надо уже имена полей клеить
2) имена полей надо эскйпить, чтобы избежать инъекций
3) если от условия зависит не только предикат, но и джоин - вот тут начинается ад.
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755617
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAgandjustasКлеить строки идеальный вариант с точки зрения результата, но без автоматизации типа Linq, крайне сложный .Ну прям-таки крайне сложный. Не преувеличивайте
По сравнению с linq сложнее раз в 10, особенно когда запросы не такие простые, как в примере.

Надо ведь еще проекцию не забыть клеить, и джоины могут зависеть от условий.
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755620
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gandjustasАлексей К,

1) для сортировок надо уже имена полей клеить
2) имена полей надо эскйпить, чтобы избежать инъекций
3) если от условия зависит не только предикат, но и джоин - вот тут начинается ад.
Забыл еще:
4) проекции тоже надо клеить
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755625
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gandjustasskyANAпропущено...
Ну прям-таки крайне сложный. Не преувеличивайте
По сравнению с linq сложнее раз в 10, особенно когда запросы не такие простые, как в примере.

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

А как будет выглыдить C# код, когда запросы не такие простые? Может следовало пример посложнее придумать?
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755633
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и главное: статья называется "Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server с помощью LINQ", - а под названием какой-то простенький надуманный пример.
Хоть бы агенду какую расписал, или слайды к докладу запостил. На какой минуте там про высоконагруженные приложения-то? Примеры из реальной практики есть?
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755641
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Кgandjustas3) клеить строки динамически и использовать sp_executesql - это гемор, ошибки и потенциальные SQL инъекции.Всегда так делали. Никакого гемора, никаких инъекций. С точки зрения плана выполнения, результат ничем не отличается от запуска через LINQ.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
-- ...............

if @p is not null
    set @sql = @sql + ' and t.ShippedDate = @p'
else
    set @sql = @sql + ' and t.ShippedDate is null'

exec sp_executesql @sql, '@p datetime', @p


В топку классическое императивное мышление.
Код: sql
1.
2.
3.
4.
.......
where 
.......
and (@p is null or t.ShippedDate = @p)
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755661
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gandjustas Процедура оптимизируется один раз при первом вызове с учетом фактических параметров.
У процедуры, в плане построения плана, над простым запросом, только одно преимущество, план ее выполнения с большей вероятностью будет находиться в кеше планов.
Более того, у процедуры может быть стопицот планов, в зависимости от параметров, фрагментации индексов и того, с какой ноги встала сегодня жена Барака Обамы.
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755673
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВАлексей Кпропущено...
Всегда так делали. Никакого гемора, никаких инъекций. С точки зрения плана выполнения, результат ничем не отличается от запуска через LINQ.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
-- ...............

if @p is not null
    set @sql = @sql + ' and t.ShippedDate = @p'
else
    set @sql = @sql + ' and t.ShippedDate is null'

exec sp_executesql @sql, '@p datetime', @p


В топку классическое императивное мышление.
Код: sql
1.
2.
3.
4.
.......
where 
.......
and (@p is null or t.ShippedDate = @p)

В топку Index Seek ?
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38755680
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gandjustasАлексей К,

1) для сортировок надо уже имена полей клеитьНе проблема.
gandjustas2) имена полей надо эскйпить, чтобы избежать инъекцийЗачем? Имена полей не приходят в качестве параметра.
gandjustas3) если от условия зависит не только предикат, но и джоин - вот тут начинается ад.Ад начинается, когда нужно выделить фрагмент SQL для повторного использования. В MSSQL это решается в том числе через Scalar UDF, которые работают, мягко говоря, не быстро.

Вот тут, да - LINQ приходить на помощь: "Композиция дерева выражений и подставляемые выражения" . Но я помню, тебе не нравится такой подход, ты предпочитаешь в этом случае копипастить.
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38756217
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAЧто-то не припомню случаев, когда надо было клеить проекции, сортировки и были сложности с джоинами.
Значит все запросы у тебя простые были. Я делал систему с row-level security, вот там пришлось много генерить запросов, причем из-за кеширования ACL иногда генерировался запрос с кучей джоинов, а иногда без них, на дну и ту же выборку.

skyANAА как будет выглыдить C# код, когда запросы не такие простые? Может следовало пример посложнее придумать?
Тоже самое будет. Потому что в linq нет надобности выписывать запрос полностью. В посте указана функция, которая принимает IQueryable и возвращает IQueryable (такие функции называются комбинаторами ), во входящем IQueryable может быть запос любой сложности, который в свою очередь собирается такими же простыми (можно сказать примитивными) комбинаторами.

Но об этом не писал. ИМХО очевидно всем .NET программистам должно быть.
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38756220
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВgandjustas Процедура оптимизируется один раз при первом вызове с учетом фактических параметров.
У процедуры, в плане построения плана, над простым запросом, только одно преимущество, план ее выполнения с большей вероятностью будет находиться в кеше планов.
Более того, у процедуры может быть стопицот планов, в зависимости от параметров, фрагментации индексов и того, с какой ноги встала сегодня жена Барака Обамы.
Чушь полнейшая.
1) У процедуры ровно одни план, который оптимизируется при первом вызове с учетом конкретных параметров. Можно делать вызов with recompile, тогда план будет генерироваться при каждом вызове и не будет кешироваться.
2) Все adhoc запросы в .NET выполняются с использованием sp_executesql, которая гарантирует сохранение плана запроса в кеше.

Изучайте как работает SQL Server прежде чем писать такое.
В видео, кстати, упоминаю этот миф.
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38756226
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gandjustasskyANAЧто-то не припомню случаев, когда надо было клеить проекции, сортировки и были сложности с джоинами.
Значит все запросы у тебя простые были. Я делал систему с row-level security, вот там пришлось много генерить запросов, причем из-за кеширования ACL иногда генерировался запрос с кучей джоинов, а иногда без них, на дну и ту же выборку.

skyANAА как будет выглыдить C# код, когда запросы не такие простые? Может следовало пример посложнее придумать?
Тоже самое будет. Потому что в linq нет надобности выписывать запрос полностью. В посте указана функция, которая принимает IQueryable и возвращает IQueryable (такие функции называются комбинаторами ), во входящем IQueryable может быть запос любой сложности, который в свою очередь собирается такими же простыми (можно сказать примитивными) комбинаторами.

Но об этом не писал. ИМХО очевидно всем .NET программистам должно быть.Давай пример. А то не понятно, что у тебя в хранимке становится крайне сложным, а в linq при этом крайне просто.
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38756233
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КВот тут, да - LINQ приходить на помощь: "Композиция дерева выражений и подставляемые выражения" . Но я помню, тебе не нравится такой подход, ты предпочитаешь в этом случае копипастить.
Ты о чем? Как раз в Linq можно ничего не копипастить, используя комбинаторы.

А если нужно подставлять деревья выражений в деревья выражений, то я это еще 4 года назад придумал - http://gandjustas.blogspot.ru/2010/06/expression-tree.html
Сейчас в EF это можно прозрачно для пользователя сделать
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38756234
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gandjustasТоже самое будет. Потому что в linq нет надобности выписывать запрос полностью. В посте указана функция, которая принимает IQueryable и возвращает IQueryable (такие функции называются комбинаторами ), во входящем IQueryable может быть запос любой сложности, который в свою очередь собирается такими же простыми (можно сказать примитивными) комбинаторами.В MSSQL есть View и Inline UDF.
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38756245
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gandjustasА если нужно подставлять деревья выражений в деревья выражений, то я это еще 4 года назад придумал - http://gandjustas.blogspot.ru/2010/06/expression-tree.html
Сейчас в EF это можно прозрачно для пользователя сделатьКроме тебя это ещё придумали в BLToolkit (LINQ2DB) и в LinqKit. :-)

gandjustasСейчас в EF это можно прозрачно для пользователя сделатьКак? Кроме обёртки над LINQ-провайдером способов не вижу.
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38756279
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gandjustas1) У процедуры ровно одни план, который оптимизируется при первом вызове с учетом конкретных параметров.

Код: sql
1.
2.
3.
4.
5.
SELECT * 
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
WHERE cacheobjtype='Compiled Plan' 
ORDER BY text DESC;
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38756395
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КgandjustasТоже самое будет. Потому что в linq нет надобности выписывать запрос полностью. В посте указана функция, которая принимает IQueryable и возвращает IQueryable (такие функции называются комбинаторами ), во входящем IQueryable может быть запос любой сложности, который в свою очередь собирается такими же простыми (можно сказать примитивными) комбинаторами.В MSSQL есть View и Inline UDF.

И? композиции то нет, ты же не можешь написать так:
Код: sql
1.
select * from MakeProjection(FilterByX(FilterByY(y))

.
А в Linq ты это напишешь еще красивее:
Код: c#
1.
2.
3.
4.
ctx.Table
   .FilterByY(y)
   .FilterByX(x)
   .MakeProjection()
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38756404
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КgandjustasА если нужно подставлять деревья выражений в деревья выражений, то я это еще 4 года назад придумал - http://gandjustas.blogspot.ru/2010/06/expression-tree.html
Сейчас в EF это можно прозрачно для пользователя сделатьКроме тебя это ещё придумали в BLToolkit (LINQ2DB) и в LinqKit. :-)
Только он появился спустя год кажись ;)


Алексей ККак? Кроме обёртки над LINQ-провайдером способов не вижу.
Кроме обертки и нет способов, но у меня обертка генерируется в AOP и подсовываться вместо IDbSet. То есть в коде приложения вообще никаких изменений.
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38756421
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВgandjustas1) У процедуры ровно одни план, который оптимизируется при первом вызове с учетом конкретных параметров.

Код: sql
1.
2.
3.
4.
5.
SELECT * 
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
WHERE cacheobjtype='Compiled Plan' 
ORDER BY text DESC;




запустил скрипт из поста

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
DBCC FREEPROCCACHE
GO
 
EXEC    [dbo].[GetTransactionsByShipDate] NULL
GO
 
declare @shipdate datetime = getdate()
EXEC    [dbo].[GetTransactionsByShipDate] @shipdate
GO
 
DBCC FREEPROCCACHE
GO
 
declare @shipdate datetime = getdate()
EXEC    [dbo].[GetTransactionsByShipDate] @shipdate
GO
 
EXEC    [dbo].[GetTransactionsByShipDate] NULL
GO



Потом сделал запрос

Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT * 
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
WHERE cacheobjtype='Compiled Plan' 
		and objtype='Proc' 
		and dbid = DB_ID('ConsoleApplication9.Production')
ORDER BY text DESC;



bucketidrefcountsusecountssize_in_bytesmemory_object_addresscacheobjtypeobjtypeplan_handlepool_idparent_plan_handledbidobjectidnumberencryptedtext3072322573440x00000004743FA060Compiled PlanProc0x05000800D1D9C83490A2647F04000000010000000000000000000000000000000000000000000000000000001NULL888557819310CREATE PROCEDURE [dbo].[GetTransactionsByShipDate]

Упс, один план, используемый два раза.

Сделал много запусков с разными параметрами без сброса кеша - все равно один план.

Короче приходи ко мне на тренинг по оптимизации, научу, ориентировочно 16 октября.
...
Рейтинг: 0 / 0
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
    #38756450
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gandjustasЗначит все запросы у тебя простые были.Эхх, да, наверное не довелось...

Ни когда для ЮКОСа, Норникеля, ВНИИСТа софт писали.
Ни когда системы онлайн бронирования в реальном времени.
Ни сейчас.

Сейчас вообще тухляк, в основном к MongoDB запросы.

И на HighLoad++ никто с докладами про LINQ с проекциями не выступает. Печаль.

Пример-то будет, приближённый к реальности?
...
Рейтинг: 0 / 0
25 сообщений из 72, страница 1 из 3
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]