From 17704723d430e61fcc46cc0d7f657a177dd7335b Mon Sep 17 00:00:00 2001 From: Mark Carrington <31017244+MarkMpn@users.noreply.github.com> Date: Thu, 2 Nov 2023 19:55:46 +0000 Subject: [PATCH] Reduce custom sorts on merge joins --- .../ExecutionPlan/MergeJoinNode.cs | 75 +++++++++---------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/MergeJoinNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/MergeJoinNode.cs index d4fdb871..b4daeeff 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/MergeJoinNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/MergeJoinNode.cs @@ -217,6 +217,23 @@ public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext if (folded != this) return folded; + var hashJoin = new HashJoinNode + { + LeftSource = LeftSource, + RightSource = RightSource, + LeftAttribute = LeftAttribute, + RightAttribute = RightAttribute, + JoinType = JoinType, + AdditionalJoinCriteria = AdditionalJoinCriteria, + SemiJoin = SemiJoin + }; + + foreach (var kvp in DefinedValues) + hashJoin.DefinedValues.Add(kvp); + + hashJoin.LeftSource.Parent = hashJoin; + hashJoin.RightSource.Parent = hashJoin; + // Can't use a merge join if the join key types have different sort orders if (LeftAttribute != null && RightAttribute != null) { @@ -229,26 +246,7 @@ public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext var rightType = rightSchema.Schema[rightColumn].Type; if (!IsConsistentSortTypes(leftType, rightType)) - { - var hashJoin = new HashJoinNode - { - LeftSource = LeftSource, - RightSource = RightSource, - LeftAttribute = LeftAttribute, - RightAttribute = RightAttribute, - JoinType = JoinType, - AdditionalJoinCriteria = AdditionalJoinCriteria, - SemiJoin = SemiJoin - }; - - foreach (var kvp in DefinedValues) - hashJoin.DefinedValues.Add(kvp); - - hashJoin.LeftSource.Parent = hashJoin; - hashJoin.RightSource.Parent = hashJoin; - - return hashJoin; - } + return hashJoin.FoldQuery(context, hints); } // This is a many-to-many join if the left attribute is not unique @@ -301,27 +299,22 @@ public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext // If we couldn't fold the sorts, it's probably faster to use a hash join instead if we only want partial results var leftSort = LeftSource as SortNode; var rightSort = RightSource as SortNode; - if (Parent is TopNode && (leftSort != null || rightSort != null)) - { - var hashJoin = new HashJoinNode - { - LeftSource = leftSort?.Source ?? LeftSource, - RightSource = rightSort?.Source ?? RightSource, - LeftAttribute = LeftAttribute, - RightAttribute = RightAttribute, - JoinType = JoinType, - AdditionalJoinCriteria = AdditionalJoinCriteria, - SemiJoin = SemiJoin - }; - - foreach (var kvp in DefinedValues) - hashJoin.DefinedValues.Add(kvp); - - hashJoin.LeftSource.Parent = hashJoin; - hashJoin.RightSource.Parent = hashJoin; - - return hashJoin; - } + + if (leftSort == null && rightSort == null) + return this; + + hashJoin.LeftSource = leftSort?.Source ?? LeftSource; + hashJoin.RightSource = rightSort?.Source ?? RightSource; + + + var foldedHashJoin = hashJoin.FoldQuery(context, hints); + + if (Parent is TopNode || + leftSort != null && rightSort != null) + return foldedHashJoin; + + LeftSource.Parent = this; + RightSource.Parent = this; return this; }