C# tutorials > Frameworks and Libraries > Entity Framework Core (EF Core) > What are split queries and single queries?
What are split queries and single queries?
In Entity Framework Core (EF Core), when dealing with related data, you have options on how to load that data. Two primary approaches are using 'single queries' and 'split queries'. This tutorial explains the differences between them and how they impact performance.
Understanding Single Queries
A single query, by default in EF Core versions before 5.0, fetches all the required data (including related entities) in a single SQL query. This is achieved through the use of JOIN
operations in the generated SQL.
Example of a Single Query
In this example, context.Blogs.Include(b => b.Posts).ToList()
generates a single SQL query with a JOIN
between the Blogs
and Posts
tables. All blog and post data are retrieved in one go.
using Microsoft.EntityFrameworkCore;
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("YourConnectionStringHere");
}
}
// Fetching blogs and their posts using a single query (default behavior before EF Core 5.0):
using (var context = new BloggingContext())
{
var blogs = context.Blogs.Include(b => b.Posts).ToList();
}
Understanding Split Queries
A split query, introduced in EF Core 5.0, fetches related data using multiple SQL queries. Instead of a single query with JOIN
s, it executes separate queries for the main entity and its related entities.
Enabling Split Queries
You can enable split queries either globally for the entire DbContext
or for a specific query using AsSplitQuery()
.
// Enable split queries globally in OnConfiguring:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("YourConnectionStringHere").UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
}
// Enable split query for a specific query:
using (var context = new BloggingContext())
{
var blogs = context.Blogs.Include(b => b.Posts).AsSplitQuery().ToList();
}
Example of a Split Query
When split queries are enabled, the code snippet above generates two separate SQL queries: one to fetch all blogs and another to fetch the posts for those blogs. This avoids the use of JOIN
s.
using (var context = new BloggingContext())
{
// Assuming SplitQuery is configured globally or using AsSplitQuery()
var blogs = context.Blogs.Include(b => b.Posts).ToList();
}
//This would result in 2 queries being executed. One for the Blog and one for the Posts
When to Use Single Queries
Single queries can be more efficient when the dataset is small and the database is optimized for handling complex joins. They are often the default behavior in older EF Core versions.
When to Use Split Queries
Split queries can significantly improve performance when dealing with large datasets or complex relationships where the JOIN
operation becomes a bottleneck. They can also be beneficial when dealing with many-to-many relationships or deep object graphs.
Memory Footprint
Single Queries: The entire result set, including related entities, is materialized into memory at once. This can lead to a larger memory footprint if you're dealing with a large number of related entities.
Split Queries: The main entity and related entities are materialized separately. This can lead to a smaller initial memory footprint compared to single queries, as you're not loading everything at once. However, it might require more round trips to the database, potentially impacting overall performance if not optimized.
Pros and Cons
Real-Life Use Case
Consider a scenario where you have a Customer
entity with a one-to-many relationship to Order
entities. Each customer can have many orders. If you are fetching a list of customers and their orders, and each customer has hundreds of orders, a single query with a JOIN
could result in a very large result set (Cartesian explosion). In such a case, using split queries to fetch customers and their orders separately would significantly improve performance.
Best Practices
Interview Tip
When asked about query performance in EF Core, mentioning single and split queries demonstrates a good understanding of data loading strategies. Be prepared to discuss their tradeoffs and when each approach is most appropriate. Also, mention the importance of benchmarking to make informed decisions.
FAQ
-
Which query splitting behavior is used by default in EF Core 5.0 and later?
From EF Core 5.0, the default behavior is that EF Core decides based on the query. Complex queries will automatically use Split Queries. -
Can I force EF Core to always use single queries, even in EF Core 5.0+?
Yes, you can configure theDbContext
to use single queries globally by settingQuerySplittingBehavior.SingleQuery
in theOnConfiguring
method, or for a specific query using.AsSingleQuery()
. -
How can I tell if EF Core is using a single query or split query?
You can enable logging in EF Core to see the generated SQL queries. If you see multiple queries being executed for a singleInclude
statement, it's likely using split queries.