DEV Community

Spyros Ponaris
Spyros Ponaris

Posted on

5 1

πŸš€ Optimize EF Core Queries with AsSplitQuery()

When working with Entity Framework Core (EF Core), queries that involve multiple Include() statements can result in a single large query with multiple joins.

This can cause performance issues due to data duplication and increased memory usage.

πŸ” What is AsSplitQuery()?

AsSplitQuery() tells EF Core to fetch related data using separate SQL queries instead of one large join query. This helps optimize **performance **for complex queries with multiple related entities.

βœ… Step 1: Setup Your Model

Let’s create a simple e-commerce scenario with Order, Customer, and OrderItem entities.

public class Order
{
    public int Id { get; set; }
    public string OrderNumber { get; set; }
    public Customer Customer { get; set; }
    public List<OrderItem> OrderItems { get; set; } = new();
}

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class OrderItem
{
    public int Id { get; set; }
    public string ProductName { get; set; }
    public int Quantity { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

βš™οΈ Step 2: Configure the Database Context

Define the DbContext to include necessary DbSet properties.

public class AppDbContext : DbContext
{
    public DbSet<Order> Orders { get; set; }
    public DbSet<Customer> Customers { get; set; }
    public DbSet<OrderItem> OrderItems { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServr("set connection string");
    }
}
Enter fullscreen mode Exit fullscreen mode

πŸ§ͺ Step 3: Query Without AsSplitQuery()
Let’s say we want to fetch orders with their customers and order items:

var orders = await _context.Orders
    .Include(o => o.Customer)
    .Include(o => o.OrderItems)
    .ToListAsync();
Enter fullscreen mode Exit fullscreen mode

What Happens?

EF Core generates a single SQL query with multiple JOIN operations.
If there are many orders and items, this can cause performance issues due to data duplication and increased memory usage.

πŸš€ Step 4: Optimize with AsSplitQuery()

Now, let's improve performance using AsSplitQuery():

var orders = await _context.Orders
    .Include(o => o.Customer)
    .Include(o => o.OrderItems)
    .AsSplitQuery()
    .ToListAsync();
Enter fullscreen mode Exit fullscreen mode

What Happens Now?

  • EF Core executes multiple separate SQL queries instead of a single large join.
  • Less memory is used.
  • Duplicate data is avoided.
  • Performance improves for large datasets.

πŸ” Step 5: Understanding the SQL Queries
Without AsSplitQuery() (default behavior)

SELECT o.*, c.*, oi.*
FROM Orders o
LEFT JOIN Customers c ON o.CustomerId = c.Id
LEFT JOIN OrderItems oi ON o.Id = oi.OrderId;
Enter fullscreen mode Exit fullscreen mode

This can lead to repeated rows for the same order due to the join on OrderItems.

With AsSplitQuery()

SELECT * FROM Orders;
SELECT * FROM Customers WHERE Id IN (...);
SELECT * FROM OrderItems WHERE OrderId IN (...);
Enter fullscreen mode Exit fullscreen mode

This results in more efficient memory usage and cleaner result sets.

🌐 Configure AsSplitQuery() Globally

Instead of calling .AsSplitQuery() on every query, you can make it the default behavior for your entire app.

βœ… Add this to OnModelCreating in your DbContext:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.UseSplitQueryBehavior(SplitQueryBehavior.SplitQuery);
}
Enter fullscreen mode Exit fullscreen mode

⚠️ Requires EF Core 6.0+

πŸ“Œ Notes:

All queries with .Include() will now use split queries by default.

You can override this behavior per query using .AsSingleQuery() if needed.

πŸ“ˆ When to Use AsSplitQuery()

βœ… Use it when:

  • You include multiple navigation properties.
  • You're querying large datasets.
  • You want to avoid duplicated data and reduce memory load.

❌ Avoid it when:

  • Your queries are small/simple.
  • Network latency makes multiple queries less efficient.
  • You require strict control over transaction boundaries.

🧠 Conclusion

Using AsSplitQuery() in EF Core is a simple yet powerful optimization. Whether you configure it per-query or globally, it can significantly reduce memory usage and improve performance when working with complex data models and large datasets.

πŸ“š References

EF Core documentation: Loading Related Data β€” Split Queries

EF Core documentation: Performance considerations for split vs single queries

Source code: Ef core examples

Heroku

Amplify your impact where it matters most β€” building exceptional apps.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)