Update OrderQueries to use linq queries
A reference .NET application implementing an eCommerce site
Brought to you by:
jobily
Originally created by: AlmarAubel
OrderQueries to LINQ queries.BuyerId an auto-property to enable its use in LINQ queries.This addresses one of the points mentioned by @adityamandaleeka in issue [#23].
Originally posted by: AlmarAubel
@dotnet-policy-service agree
Originally posted by: adityamandaleeka
Tagging @roji @ajcvickers for best practices review here.
Would be great if we could see a before/after perf comparison for this sort of thing.
Originally posted by: AlmarAubel
Benchmark Comparison of Raw SQL vs EF Core Queries for GetOrdersAsync
I've completed the benchmarking as requested to assess the performance implications of transitioning from raw SQL queries to EF Core, followed by further optimizations. Initially, the queries were naively translated to EF Core with minimal modifications to the classes used in querying. Subsequently, I implemented optimizations, primarily modifying certain getter methods with a private backing field to properties with a private setter. This adjustment aids EF Core in better optimizing queries, especially for expressions like
total = (double)ob.order.GetTotal()which is replaced in the optimized version byob.order.OrderItems.Sum(oi => oi.UnitPrice* oi.Units).Results
Here are the benchmark results for GetOrdersAsync:
Analysis:
Raw SQL to Naive EF Core: The transition from raw SQL to a naive EF Core implementation resulted in a significant increase in execution time and memory allocation. This is expected as the naive approach does not take advantage of EF Core's optimization capabilities.
Naive to Optimized EF Core: Post optimization, there's a dramatic improvement, bringing the performance almost on par with the raw SQL, both in terms of execution time and memory usage. The optimizations primarily involved restructuring getter methods for better EF Core query translation.
NoTracking Variants: The 'AsNoTracking' variants show similar performance to their tracking counterparts, with a slight increase in memory usage. This indicates that tracking does not significantly impact performance in this context.
This comparison clearly illustrates the importance of proper query structuring and optimization in EF Core to achieve performance close to raw SQL. I believe these optimizations represent a more effective approach for this scenario.
SQL
For reference, here are the queries:
Raw SQL:
Optimized:
Naive:
Next steps
Based on these insights, I propose further refactoring to enhance our application's performance and maintainability. If your agrees with this approach, I plan to:
Disclaimer :)
Please let me know if you agree with this direction. Upon confirmation, I'll proceed with the necessary modifications and update the PR accordingly.
Finally, I'd like to emphasize that benchmarking is a complex area, often with nuanced results. I've tried to ensure that the methodology I chose is suitable for this context, but I'm open to feedback or alternative approaches that could refine our understanding of the performance impacts.
You can find the code used for the benchmarks here.
edit 2023-12-10:
I've revised the benchmarking to evaluate the performance implications of transitioning from raw SQL queries to EF Core, incorporating further optimizations and a new approach to data retrieval.
• I have updated the approach so that we no longer retrieve the same order from the database every time. Instead, we now select one from 1000 items randomly. It appears there is a significant difference between items. For example, the 50th item is always faster with EF Core, but the 24th item is consistently quicker with the raw SQL variant.
• Moreover, added a compiled query variant, which is faster and allocates less memory.
Originally posted by: AlmarAubel
Benchmark Comparison of Raw SQL vs EF Core Queries
I've recently conducted a benchmark to compare the performance of raw SQL implementations against EF Core queries.
Firstly, it's important to note that I excluded the connection setup time from the benchmark. This decision was made to focus solely on the query execution performance. Including connection setup could introduce variability unrelated to the query performance itself, especially in scenarios where connection pooling or other optimizations are in play. By excluding this, we get a clearer picture of how the queries themselves are performing.
Here are the results:
The results show that EF Core queries generally perform better in terms of execution time, although they sometimes allocate more memory. This trade-off might be worth considering based on the project's specific needs and constraints.
SQL
GetOrderAsync
Raw
Ef core generated
GetOrderAsync
See previous post
GetCardTypesAsync
Raw
Ef core generated