EF Core Split Queries vs Single Queries: A Decision Guide for Loading Related Data
Decide between EF Core split and single queries when using Include: a comparison table, the real trade-offs (round-trips vs row duplication), and how to verify the generated SQL.
23 Jan 2026, 01:09 UTC

When you load related data with Include(), EF Core must decide how to translate that into SQL. By default, it issues one query with JOINs. Since EF Core 5, you can instead request one query per collection navigation. Picking the wrong mode for your data shape either floods the network with duplicated rows or adds avoidable round-trips. This guide provides a decision rule, a comparison, and a way to verify the choice against your own database.
The decision and its constraints
The problem only exists for collection navigations (one-to-many or many-to-many). Reference navigations (many-to-one) join cleanly and never trigger the issue, so the choice is irrelevant there.
With a single query, each parent row is repeated once per child row. If a blog has 100 posts, the blog's columns are sent 100 times. With two collection includes (posts and comments), the duplication multiplies—this is the Cartesian product problem. Split queries avoid this by fetching each collection in a separate SELECT, at the cost of extra round-trips.
Options compared
| Aspect | Single Query (default) | Split Query |
|---|---|---|
| SQL generated | One SELECT with JOINs | One SELECT per collection |
| Round-trips | 1 | 1 + number of collections |
| Duplicate parent data | Yes — grows with collections | No |
| Best for | Small collections, low latency | Large collections, wide rows |
| Main risk | Cartesian explosion | Latency; data inconsistency |
| Tracking behavior | Standard | Slightly more tracker memory |
Trade-offs that actually matter
Network latency vs payload size. On a high-latency link (e.g., cloud database across regions), each extra round-trip can cost tens of milliseconds, so prefer single queries unless duplication is severe. On a fast LAN with wide rows and big collections, split queries usually win.
Consistency. Split queries execute as separate statements. Without a transaction, another writer can modify data between them, so the parent and children may reflect different points in time. If you need a consistent snapshot, wrap the read in a transaction (e.g., Serializable or RepeatableRead on SQL Server) or use a single query.
Ordering. With split queries, always specify a deterministic OrderBy on the parent key if you also page (Skip/Take); otherwise rows can be associated with the wrong parent across the separate result sets.
Concrete implementation
Per-query control (EF Core 5 or later), run inside your application code where the DbContext is available:
// One blog with its posts, fetched as two SELECT statements
var blogs = await context.Blogs
.Include(b => b.Posts)
.AsSplitQuery()
.ToListAsync();
// Force the default JOIN behavior even if split is configured globally
var blogs = await context.Blogs
.Include(b => b.Posts)
.AsSingleQuery()
.ToListAsync();Global default, configured once in OnConfiguring or where you build options (no special permissions needed beyond normal database access):
options.UseSqlServer(connectionString, o =
o.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery));With a global split default, use AsSingleQuery() on the specific queries where JOINs are cheaper.
Validating the choice
Enable EF Core logging to inspect the generated SQL. The simplest approach is LogTo:
options.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging(); // dev only: shows parametersRun the include query once with and once without AsSplitQuery(). Expected result: the split version shows two separate SELECT statements (one for blogs, one for posts); the single version shows one SELECT with a JOIN. Do not assume—confirm in the log, because some shapes (filtered includes, projections) change the SQL.
To make the decision with data, compare the two modes on a realistic dataset: log the total rows returned over the wire and time both variants end-to-end. A parent with many children and wide columns (e.g., a large text column) will show obvious duplication in single-query mode.
Limitations
- Split queries do not help with reference navigations; they only change collection loading.
- Behavior described applies to EF Core 5 through current 8.x releases; verify against your version's release notes.
- Some providers or query shapes may ignore the hint; the generated SQL log is the source of truth.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.