|
Неоптимальность генерируемого EF Core sql-запроса
|
|||
---|---|---|---|
#18+
Всем привет, есть Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39.
есть сама накладная Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44.
Смысл такой архитектуры в том, что есть базовые характеристики накладной, которые не меняются после её создания- номер, первоначальный создатель, а есть изменяющаяся информация, которая прикреплена к этой накладной (набор товаров, отправитель, получатель и тд). Изменяющаяся она потому что содержание накладной можно пересоздавать- например пользователь заметил, что неправильно создал её и хочет перепечатать с новым набором товаров. Но при этом, все напечатанные версии накладной должны храниться и актуальной является самая последняя по дате создания (CreationDate). У меня возникает необходимость вывести список накладных с содержанием. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
EF Core в транслирует Linq в жутко неоптимальный sql-запрос Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26.
То есть формируется много паразитных LEFT JOIN, хотя достаточно всего лишь 2. Понятно, что это из-за того, что я тянусь к вложенным свойствам t.Invoices.OrderBy(g=>g.CreationDate).Last(). Можно как-либо в секции Select замутить что-то вроде Код: c# 1. 2. 3. 4. 5. 6.
что бы EF Core не генирировал дублирующие left join, потому что на нормальном количестве данных такой запрос будет тормозить. Спасибо ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2020, 10:29 |
|
Неоптимальность генерируемого EF Core sql-запроса
|
|||
---|---|---|---|
#18+
ничто не мешает написать join ручками в linq-запросе ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2020, 10:39 |
|
Неоптимальность генерируемого EF Core sql-запроса
|
|||
---|---|---|---|
#18+
Shocker.Pro, Вы имеете ввиду FromSqlRaw? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2020, 10:46 |
|
Неоптимальность генерируемого EF Core sql-запроса
|
|||
---|---|---|---|
#18+
vb_sub EF Core в транслирует Linq в жутко неоптимальный sql-запрос Это не запрос "не оптимальный". Это модель данных ущербная. SQL конечно способен вытянуть данные быстро из любого г-на. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2020, 11:05 |
|
Неоптимальность генерируемого EF Core sql-запроса
|
|||
---|---|---|---|
#18+
vb_sub Shocker.Pro, Вы имеете ввиду FromSqlRaw? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2020, 11:07 |
|
Неоптимальность генерируемого EF Core sql-запроса
|
|||
---|---|---|---|
#18+
hVostt vb_sub EF Core в транслирует Linq в жутко неоптимальный sql-запрос Это не запрос "не оптимальный". Это модель данных ущербная. SQL конечно способен вытянуть данные быстро из любого г-на. Как должен выглядеть неущербный вариант? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2020, 11:32 |
|
Неоптимальность генерируемого EF Core sql-запроса
|
|||
---|---|---|---|
#18+
vb_sub Как должен выглядеть неущербный вариант? Моделируйте прежде всего с точки зрения бизнеса. Для примера, как вариант: У вас должна быть лишь сущность накладной, без разбивки на "изменяемую" и "неизменяемую" части -- таких понятий в бизнесе нет. Но вам нужна также история, ведите её отдельно. Таким образом, чтобы наличие или отсутствие истории никак не влияло на основную логику. Получается, что у вас будет 1. Invoice -- полная сущность накладной. 2. InvoiceHistory -- архивная сущность накладной. Хотите работать с историей, работаете с InvoiceHistory. Хотите работать с текущими актуальными данными, работаете с Invoice. Посмотрите, как это положительно скажется, на размере, скорости работы запросов, а также вы уберёте лишние грабли, на которые очень легко наступить в вашей схеме. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2020, 12:21 |
|
Неоптимальность генерируемого EF Core sql-запроса
|
|||
---|---|---|---|
#18+
Судить о том, насколько запрос "оптимальный" или "неоптимальный" можно только по его плану выполнения на sql-сервере, а никак не по тексту самого запроса. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.02.2020, 17:30 |
|
Неоптимальность генерируемого EF Core sql-запроса
|
|||
---|---|---|---|
#18+
fkthat Судить о том, насколько запрос "оптимальный" или "неоптимальный" можно только по его плану выполнения на sql-сервере, а никак не по тексту самого запроса. Как общий подход -- да, так. Но у запросов могут быть другие проблемы, кроме плана. И по-серьёзней. Текст смотреть тоже нужно. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2020, 00:03 |
|
Неоптимальность генерируемого EF Core sql-запроса
|
|||
---|---|---|---|
#18+
fkthat Судить о том, насколько запрос "оптимальный" или "неоптимальный" можно только по его плану выполнения на sql-сервере, а никак не по тексту самого запроса. Согласен, тут более подходит определение "избыточен", чем "неоптимален" ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2020, 08:45 |
|
Неоптимальность генерируемого EF Core sql-запроса
|
|||
---|---|---|---|
#18+
vb_sub Согласен, тут более подходит определение "избыточен", чем "неоптимален" А что в этом за печаль - ты же не руками этот запрос пишешь. Теоретически, запрос может быть плохой даже при хорошем плане, если он какой-то такой, что не позволяет этот план серверу закешировать, чего-то другого мне на ум так сразу не приходит. Но, сам сиквел уже года по-моему чуть ли не с 2005 с этим успешно справляется (самостоятельно выносит литералы из запроса в параметры). ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2020, 10:32 |
|
|
start [/forum/topic.php?fid=17&fpage=2&tid=1349084]: |
0ms |
get settings: |
11ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
27ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
48ms |
get tp. blocked users: |
2ms |
others: | 234ms |
total: | 358ms |
0 / 0 |