|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
Публикую материалы доклада с 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 и управление проектами. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 02:19 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
gandjustas, а если обычный разработчик напишет в хранимой процедуре два запроса (как и с помощью Linq), а не один? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 08:37 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
skyANAgandjustas, а если обычный разработчик напишет в хранимой процедуре два запроса (как и с помощью Linq), а не один? Будет тот же эффект. Процедура оптимизируется один раз при первом вызове с учетом фактических параметров. Обойти на уровне SQL можно тремя способами: 1) вызывать процедуру WITH RECOMPILE - самый плохой способ 2) Сделать две процедуры с разными запросами и одну, которая их вызывает, но это дублирование кода будет аццкое 3) клеить строки динамически и использовать sp_executesql - это гемор, ошибки и потенциальные SQL инъекции. Клеить строки идеальный вариант с точки зрения результата, но без автоматизации типа Linq, крайне сложный. С Linq (почти) все просто. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 09:30 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
gandjustasКлеить строки идеальный вариант с точки зрения результата, но без автоматизации типа Linq, крайне сложный .Ну прям-таки крайне сложный. Не преувеличивайте ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 09:39 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
gandjustas3) клеить строки динамически и использовать sp_executesql - это гемор, ошибки и потенциальные SQL инъекции.Всегда так делали. Никакого гемора, никаких инъекций. С точки зрения плана выполнения, результат ничем не отличается от запуска через LINQ. Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 09:42 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
Алексей К, 1) для сортировок надо уже имена полей клеить 2) имена полей надо эскйпить, чтобы избежать инъекций 3) если от условия зависит не только предикат, но и джоин - вот тут начинается ад. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 09:52 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
skyANAgandjustasКлеить строки идеальный вариант с точки зрения результата, но без автоматизации типа Linq, крайне сложный .Ну прям-таки крайне сложный. Не преувеличивайте По сравнению с linq сложнее раз в 10, особенно когда запросы не такие простые, как в примере. Надо ведь еще проекцию не забыть клеить, и джоины могут зависеть от условий. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 09:54 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
gandjustasАлексей К, 1) для сортировок надо уже имена полей клеить 2) имена полей надо эскйпить, чтобы избежать инъекций 3) если от условия зависит не только предикат, но и джоин - вот тут начинается ад. Забыл еще: 4) проекции тоже надо клеить ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 09:55 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
gandjustasskyANAпропущено... Ну прям-таки крайне сложный. Не преувеличивайте По сравнению с linq сложнее раз в 10, особенно когда запросы не такие простые, как в примере. Надо ведь еще проекцию не забыть клеить, и джоины могут зависеть от условий.Что-то не припомню случаев, когда надо было клеить проекции, сортировки и были сложности с джоинами. А как будет выглыдить C# код, когда запросы не такие простые? Может следовало пример посложнее придумать? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 10:01 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
Ну и главное: статья называется "Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server с помощью LINQ", - а под названием какой-то простенький надуманный пример. Хоть бы агенду какую расписал, или слайды к докладу запостил. На какой минуте там про высоконагруженные приложения-то? Примеры из реальной практики есть? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 10:08 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
Алексей Кgandjustas3) клеить строки динамически и использовать sp_executesql - это гемор, ошибки и потенциальные SQL инъекции.Всегда так делали. Никакого гемора, никаких инъекций. С точки зрения плана выполнения, результат ничем не отличается от запуска через LINQ. Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
В топку классическое императивное мышление. Код: sql 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 10:11 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
gandjustas Процедура оптимизируется один раз при первом вызове с учетом фактических параметров. У процедуры, в плане построения плана, над простым запросом, только одно преимущество, план ее выполнения с большей вероятностью будет находиться в кеше планов. Более того, у процедуры может быть стопицот планов, в зависимости от параметров, фрагментации индексов и того, с какой ноги встала сегодня жена Барака Обамы. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 10:18 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
ЕвгенийВАлексей Кпропущено... Всегда так делали. Никакого гемора, никаких инъекций. С точки зрения плана выполнения, результат ничем не отличается от запуска через LINQ. Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
В топку классическое императивное мышление. Код: sql 1. 2. 3. 4.
В топку Index Seek ? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 10:24 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
gandjustasАлексей К, 1) для сортировок надо уже имена полей клеитьНе проблема. gandjustas2) имена полей надо эскйпить, чтобы избежать инъекцийЗачем? Имена полей не приходят в качестве параметра. gandjustas3) если от условия зависит не только предикат, но и джоин - вот тут начинается ад.Ад начинается, когда нужно выделить фрагмент SQL для повторного использования. В MSSQL это решается в том числе через Scalar UDF, которые работают, мягко говоря, не быстро. Вот тут, да - LINQ приходить на помощь: "Композиция дерева выражений и подставляемые выражения" . Но я помню, тебе не нравится такой подход, ты предпочитаешь в этом случае копипастить. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 10:31 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
skyANAЧто-то не припомню случаев, когда надо было клеить проекции, сортировки и были сложности с джоинами. Значит все запросы у тебя простые были. Я делал систему с row-level security, вот там пришлось много генерить запросов, причем из-за кеширования ACL иногда генерировался запрос с кучей джоинов, а иногда без них, на дну и ту же выборку. skyANAА как будет выглыдить C# код, когда запросы не такие простые? Может следовало пример посложнее придумать? Тоже самое будет. Потому что в linq нет надобности выписывать запрос полностью. В посте указана функция, которая принимает IQueryable и возвращает IQueryable (такие функции называются комбинаторами ), во входящем IQueryable может быть запос любой сложности, который в свою очередь собирается такими же простыми (можно сказать примитивными) комбинаторами. Но об этом не писал. ИМХО очевидно всем .NET программистам должно быть. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 14:40 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
ЕвгенийВgandjustas Процедура оптимизируется один раз при первом вызове с учетом фактических параметров. У процедуры, в плане построения плана, над простым запросом, только одно преимущество, план ее выполнения с большей вероятностью будет находиться в кеше планов. Более того, у процедуры может быть стопицот планов, в зависимости от параметров, фрагментации индексов и того, с какой ноги встала сегодня жена Барака Обамы. Чушь полнейшая. 1) У процедуры ровно одни план, который оптимизируется при первом вызове с учетом конкретных параметров. Можно делать вызов with recompile, тогда план будет генерироваться при каждом вызове и не будет кешироваться. 2) Все adhoc запросы в .NET выполняются с использованием sp_executesql, которая гарантирует сохранение плана запроса в кеше. Изучайте как работает SQL Server прежде чем писать такое. В видео, кстати, упоминаю этот миф. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 14:43 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
gandjustasskyANAЧто-то не припомню случаев, когда надо было клеить проекции, сортировки и были сложности с джоинами. Значит все запросы у тебя простые были. Я делал систему с row-level security, вот там пришлось много генерить запросов, причем из-за кеширования ACL иногда генерировался запрос с кучей джоинов, а иногда без них, на дну и ту же выборку. skyANAА как будет выглыдить C# код, когда запросы не такие простые? Может следовало пример посложнее придумать? Тоже самое будет. Потому что в linq нет надобности выписывать запрос полностью. В посте указана функция, которая принимает IQueryable и возвращает IQueryable (такие функции называются комбинаторами ), во входящем IQueryable может быть запос любой сложности, который в свою очередь собирается такими же простыми (можно сказать примитивными) комбинаторами. Но об этом не писал. ИМХО очевидно всем .NET программистам должно быть.Давай пример. А то не понятно, что у тебя в хранимке становится крайне сложным, а в linq при этом крайне просто. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 14:45 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
Алексей КВот тут, да - LINQ приходить на помощь: "Композиция дерева выражений и подставляемые выражения" . Но я помню, тебе не нравится такой подход, ты предпочитаешь в этом случае копипастить. Ты о чем? Как раз в Linq можно ничего не копипастить, используя комбинаторы. А если нужно подставлять деревья выражений в деревья выражений, то я это еще 4 года назад придумал - http://gandjustas.blogspot.ru/2010/06/expression-tree.html Сейчас в EF это можно прозрачно для пользователя сделать ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 14:49 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
gandjustasТоже самое будет. Потому что в linq нет надобности выписывать запрос полностью. В посте указана функция, которая принимает IQueryable и возвращает IQueryable (такие функции называются комбинаторами ), во входящем IQueryable может быть запос любой сложности, который в свою очередь собирается такими же простыми (можно сказать примитивными) комбинаторами.В MSSQL есть View и Inline UDF. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 14:49 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
gandjustasА если нужно подставлять деревья выражений в деревья выражений, то я это еще 4 года назад придумал - http://gandjustas.blogspot.ru/2010/06/expression-tree.html Сейчас в EF это можно прозрачно для пользователя сделатьКроме тебя это ещё придумали в BLToolkit (LINQ2DB) и в LinqKit. :-) gandjustasСейчас в EF это можно прозрачно для пользователя сделатьКак? Кроме обёртки над LINQ-провайдером способов не вижу. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 14:56 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
gandjustas1) У процедуры ровно одни план, который оптимизируется при первом вызове с учетом конкретных параметров. Код: sql 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 15:20 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
Алексей КgandjustasТоже самое будет. Потому что в linq нет надобности выписывать запрос полностью. В посте указана функция, которая принимает IQueryable и возвращает IQueryable (такие функции называются комбинаторами ), во входящем IQueryable может быть запос любой сложности, который в свою очередь собирается такими же простыми (можно сказать примитивными) комбинаторами.В MSSQL есть View и Inline UDF. И? композиции то нет, ты же не можешь написать так: Код: sql 1.
. А в Linq ты это напишешь еще красивее: Код: c# 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 16:30 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
Алексей КgandjustasА если нужно подставлять деревья выражений в деревья выражений, то я это еще 4 года назад придумал - http://gandjustas.blogspot.ru/2010/06/expression-tree.html Сейчас в EF это можно прозрачно для пользователя сделатьКроме тебя это ещё придумали в BLToolkit (LINQ2DB) и в LinqKit. :-) Только он появился спустя год кажись ;) Алексей ККак? Кроме обёртки над LINQ-провайдером способов не вижу. Кроме обертки и нет способов, но у меня обертка генерируется в AOP и подсовываться вместо IDbSet. То есть в коде приложения вообще никаких изменений. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 16:34 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
ЕвгенийВgandjustas1) У процедуры ровно одни план, который оптимизируется при первом вызове с учетом конкретных параметров. Код: sql 1. 2. 3. 4. 5.
запустил скрипт из поста Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Потом сделал запрос Код: sql 1. 2. 3. 4. 5. 6. 7.
bucketidrefcountsusecountssize_in_bytesmemory_object_addresscacheobjtypeobjtypeplan_handlepool_idparent_plan_handledbidobjectidnumberencryptedtext3072322573440x00000004743FA060Compiled PlanProc0x05000800D1D9C83490A2647F04000000010000000000000000000000000000000000000000000000000000001NULL888557819310CREATE PROCEDURE [dbo].[GetTransactionsByShipDate] Упс, один план, используемый два раза. Сделал много запусков с разными параметрами без сброса кеша - все равно один план. Короче приходи ко мне на тренинг по оптимизации, научу, ориентировочно 16 октября. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 16:49 |
|
Оптимизация высоконагруженных ASP.NET приложений, работающих с SQL Server с помощью LINQ
|
|||
---|---|---|---|
#18+
gandjustasЗначит все запросы у тебя простые были.Эхх, да, наверное не довелось... Ни когда для ЮКОСа, Норникеля, ВНИИСТа софт писали. Ни когда системы онлайн бронирования в реальном времени. Ни сейчас. Сейчас вообще тухляк, в основном к MongoDB запросы. И на HighLoad++ никто с докладами про LINQ с проекциями не выступает. Печаль. Пример-то будет, приближённый к реальности? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2014, 17:06 |
|
|
start [/forum/topic.php?fid=17&msg=38756421&tid=1349706]: |
0ms |
get settings: |
7ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
345ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
50ms |
get tp. blocked users: |
1ms |
others: | 275ms |
total: | 713ms |
0 / 0 |