Query optimization: remove inner join from subquery navigation contains
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
Research direction
Reproduce the Where_subquery_on_navigation test described in the issue and inspect the generated SQL for the navigation Contains query. Compare the current and proposed SQL, then verify that same-table inner joins are eliminated without changing the result or query semantics.
Written by the indexing model from the issue text.
Description
When a sub query uses Contains on a navigation, like the following:
[ConditionalFact]
public virtual void Where_subquery_on_navigation()
{
using (var context = CreateContext())
{
var query = from p in context.Products
where p.OrderDetails.Contains(context.OrderDetails.FirstOrDefault(orderDetail => orderDetail.Quantity == 1))
select p;
var result = query.ToList();
Assert.Equal(1, result.Count);
}
}
The SQL contains an inner join on the same table:
SELECT [p].[ProductID], [p].[Discontinued], [p].[ProductName], [p].[UnitsInStock]
FROM [Products] AS [p]
WHERE (
SELECT CASE
WHEN EXISTS (
SELECT 1
FROM (
SELECT [o].[OrderID], [o].[ProductID]
FROM [Order Details] AS [o]
WHERE [p].[ProductID] = [o].[ProductID]
) AS [t]
INNER JOIN (
SELECT TOP(1) [orderDetail].[OrderID], [orderDetail].[ProductID]
FROM [Order Details] AS [orderDetail]
WHERE [orderDetail].[Quantity] = 1
) AS [t0] ON ([t].[OrderID] = [t0].[OrderID]) AND ([t].[ProductID] = [t0].[ProductID]))
THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END
) = 1
In cases where the Inner Join is on the same table, it may be possible to eliminate the join
SELECT [p].[ProductID], [p].[Discontinued], [p].[ProductName], [p].[UnitsInStock]
FROM [Products] AS [p]
WHERE (
SELECT CASE
WHEN EXISTS (
SELECT 1
FROM (
SELECT TOP(1) [orderDetail].[ProductID]
FROM [Order Details] AS [orderDetail]
WHERE [orderDetail].[Quantity] = 1
) AS [t]
WHERE [p].[ProductID] = [t].[ProductID])
THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END
) = 1
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 134
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from dotnet/efcore
-
Difficulty 4/5 3-5 days Newbie friendliness 55/100
-
customer-reported
Difficulty 5/5 Over a week Newbie friendliness 38/100
-
area-cosmos area-vector-search
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
area-cosmos
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
area-tools needs-design
Difficulty 4/5 3-5 days Newbie friendliness 25/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
:watch: Not Triaged 11.0 fundamentals/subsvc
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
dotnet/AspNetCore.Docs#37699 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SubtitleEdit/subtitleedit#15108 · 1 comment ·
-
area/docs-content Bug pulumi/docs
Difficulty 1/5 1-3 hours Newbie friendliness 94/100
-
agentic-workflows untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 76/100