How to rewrite CASE expression to short-circuit evaluationMySQL optimization - year column grouping - using...

Does C have an equivalent of std::less from C++?

If we should encrypt the message rather than the method of transfer, why do we care about wifi security? Is this just security theatre?

Digit Date Range

Why is Trump releasing (or not) his tax returns such a big deal?

Is there any research on the development of attacks against artificial intelligence systems?

What happens when supercritical fuel tanks deplete below critical point?

In the twin paradox does the returning twin also come back permanently length contracted flatter than the twin on Earth?

How much does freezing grapes longer sweeten them more?

Why did my relationship with my wife go down by two hearts?

How to use blackboard bold numbers with the Palatino (mathpazo) font?

If you revoke a certificate authority's certificate, do all of the certificates it issued become invalid as well?

I need an automatic way of making a lot of numbered folders

Can an idea be a being?

Why is 10.1.255.255 an invalid broadcast address?

How can I make a smooth transition from being a Black-Box Tester to an expert Automation Engineer?

Why were germanium diodes so fast and germanium transisters so slow?

How long does it take to sail to Evermeet from the Neverwinter harbor?

Who inspired the character Geordi La Forge?

Charges from Dollar General have never shown up on my debit card. How can I resolve this?

Labeling lines that are not within polygons using field calculator

Should all required user story assets be available before sizing a story or starting the sprint?

Moonlight bright enough to see by

Is it allowed to let the engine of an aircraft idle without a pilot in the plane. (For both helicopters and aeroplanes)

Does code obfuscation give any measurable security benefit?



How to rewrite CASE expression to short-circuit evaluation


MySQL optimization - year column grouping - using temporary table, filesortfiltered index null and > 0 disparity — need explanationOracle GoldenGate add trandata errorsIdentical query, tables, but different EXPLAIN and performanceSlow INSERT/UPDATE on InnoDBMySQL query taking too longInvestigating errors from strange queryMeasure Agent Job failure and running jobs with 'execution_status'Short circuit in JOINShort circuit count query






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{
margin-bottom:0;
}








1

















I would like to know if there is any way to rewrite the EXPRESSION in the query (just expression, not the whole query) to short-circuit useless evaluation of THEN phase?



Demo data:



CREATE TABLE #Docs (
ID INT NOT NULL
,DocType TINYINT NOT NULL
);

CREATE TABLE #DocsItems (
IDDocs INT NOT NULL
,Amount NUMERIC(19,6)
);

INSERT INTO #Docs(ID, DocType) VALUES(1,1),(2,1),(3,2),(4,2),(5,2),(6,2);
INSERT INTO #DocsItems(IDDocs,Amount) VALUES(3,50.),(3,25.),(3,33.),(4,44.),(4,123.),(6,11.);


Subject query:



SELECT
-- expression
SumAmount = CASE
WHEN D.DocType <> 1 THEN (SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID)
END
FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False


Query plan:
enter image description here



If I rewrite the query (on purpose) to:



SELECT
-- expression
SumAmount = CASE
WHEN 2 = 1 /* rewrite*/ THEN (SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID)
END
FROM #Docs D
WHERE D.DocType = 1


The plan goes the way it should / could / would in the original query:
enter image description here










share|improve this question
























  • 1





    What exactly do you mean? This isn't clear for me

    – George.Palacios
    8 hours ago











  • It's doing useless nested loop with #DocsItems table table scan. I know that in MS SQL Server CASE not always short-circuits - this is the example. I want to know if there is a way to rewrite this expression to short-circuit evaluation of this - always false - condition.

    – jerik1
    8 hours ago













  • table scan happens if there are not enough rows for an index to make sense or no index also why sum if you exclude it in your where statement, if at all you better have a union where you merge 2 statements one with the sum and one exclude the sum and return 0 or null

    – PPann
    8 hours ago






  • 1





    @PPann this is not the point of my question, sorry for being so unclear, don't know how to say it other way. I counted on you get it from demo code and actual plan

    – jerik1
    7 hours ago


















1

















I would like to know if there is any way to rewrite the EXPRESSION in the query (just expression, not the whole query) to short-circuit useless evaluation of THEN phase?



Demo data:



CREATE TABLE #Docs (
ID INT NOT NULL
,DocType TINYINT NOT NULL
);

CREATE TABLE #DocsItems (
IDDocs INT NOT NULL
,Amount NUMERIC(19,6)
);

INSERT INTO #Docs(ID, DocType) VALUES(1,1),(2,1),(3,2),(4,2),(5,2),(6,2);
INSERT INTO #DocsItems(IDDocs,Amount) VALUES(3,50.),(3,25.),(3,33.),(4,44.),(4,123.),(6,11.);


Subject query:



SELECT
-- expression
SumAmount = CASE
WHEN D.DocType <> 1 THEN (SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID)
END
FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False


Query plan:
enter image description here



If I rewrite the query (on purpose) to:



SELECT
-- expression
SumAmount = CASE
WHEN 2 = 1 /* rewrite*/ THEN (SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID)
END
FROM #Docs D
WHERE D.DocType = 1


The plan goes the way it should / could / would in the original query:
enter image description here










share|improve this question
























  • 1





    What exactly do you mean? This isn't clear for me

    – George.Palacios
    8 hours ago











  • It's doing useless nested loop with #DocsItems table table scan. I know that in MS SQL Server CASE not always short-circuits - this is the example. I want to know if there is a way to rewrite this expression to short-circuit evaluation of this - always false - condition.

    – jerik1
    8 hours ago













  • table scan happens if there are not enough rows for an index to make sense or no index also why sum if you exclude it in your where statement, if at all you better have a union where you merge 2 statements one with the sum and one exclude the sum and return 0 or null

    – PPann
    8 hours ago






  • 1





    @PPann this is not the point of my question, sorry for being so unclear, don't know how to say it other way. I counted on you get it from demo code and actual plan

    – jerik1
    7 hours ago














1












1








1








I would like to know if there is any way to rewrite the EXPRESSION in the query (just expression, not the whole query) to short-circuit useless evaluation of THEN phase?



Demo data:



CREATE TABLE #Docs (
ID INT NOT NULL
,DocType TINYINT NOT NULL
);

CREATE TABLE #DocsItems (
IDDocs INT NOT NULL
,Amount NUMERIC(19,6)
);

INSERT INTO #Docs(ID, DocType) VALUES(1,1),(2,1),(3,2),(4,2),(5,2),(6,2);
INSERT INTO #DocsItems(IDDocs,Amount) VALUES(3,50.),(3,25.),(3,33.),(4,44.),(4,123.),(6,11.);


Subject query:



SELECT
-- expression
SumAmount = CASE
WHEN D.DocType <> 1 THEN (SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID)
END
FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False


Query plan:
enter image description here



If I rewrite the query (on purpose) to:



SELECT
-- expression
SumAmount = CASE
WHEN 2 = 1 /* rewrite*/ THEN (SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID)
END
FROM #Docs D
WHERE D.DocType = 1


The plan goes the way it should / could / would in the original query:
enter image description here










share|improve this question

















I would like to know if there is any way to rewrite the EXPRESSION in the query (just expression, not the whole query) to short-circuit useless evaluation of THEN phase?



Demo data:



CREATE TABLE #Docs (
ID INT NOT NULL
,DocType TINYINT NOT NULL
);

CREATE TABLE #DocsItems (
IDDocs INT NOT NULL
,Amount NUMERIC(19,6)
);

INSERT INTO #Docs(ID, DocType) VALUES(1,1),(2,1),(3,2),(4,2),(5,2),(6,2);
INSERT INTO #DocsItems(IDDocs,Amount) VALUES(3,50.),(3,25.),(3,33.),(4,44.),(4,123.),(6,11.);


Subject query:



SELECT
-- expression
SumAmount = CASE
WHEN D.DocType <> 1 THEN (SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID)
END
FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False


Query plan:
enter image description here



If I rewrite the query (on purpose) to:



SELECT
-- expression
SumAmount = CASE
WHEN 2 = 1 /* rewrite*/ THEN (SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID)
END
FROM #Docs D
WHERE D.DocType = 1


The plan goes the way it should / could / would in the original query:
enter image description here







sql-server performance query-performance execution-plan






share|improve this question
















share|improve this question













share|improve this question




share|improve this question








edited 7 hours ago







jerik1

















asked 8 hours ago









jerik1jerik1

3271 silver badge11 bronze badges




3271 silver badge11 bronze badges











  • 1





    What exactly do you mean? This isn't clear for me

    – George.Palacios
    8 hours ago











  • It's doing useless nested loop with #DocsItems table table scan. I know that in MS SQL Server CASE not always short-circuits - this is the example. I want to know if there is a way to rewrite this expression to short-circuit evaluation of this - always false - condition.

    – jerik1
    8 hours ago













  • table scan happens if there are not enough rows for an index to make sense or no index also why sum if you exclude it in your where statement, if at all you better have a union where you merge 2 statements one with the sum and one exclude the sum and return 0 or null

    – PPann
    8 hours ago






  • 1





    @PPann this is not the point of my question, sorry for being so unclear, don't know how to say it other way. I counted on you get it from demo code and actual plan

    – jerik1
    7 hours ago














  • 1





    What exactly do you mean? This isn't clear for me

    – George.Palacios
    8 hours ago











  • It's doing useless nested loop with #DocsItems table table scan. I know that in MS SQL Server CASE not always short-circuits - this is the example. I want to know if there is a way to rewrite this expression to short-circuit evaluation of this - always false - condition.

    – jerik1
    8 hours ago













  • table scan happens if there are not enough rows for an index to make sense or no index also why sum if you exclude it in your where statement, if at all you better have a union where you merge 2 statements one with the sum and one exclude the sum and return 0 or null

    – PPann
    8 hours ago






  • 1





    @PPann this is not the point of my question, sorry for being so unclear, don't know how to say it other way. I counted on you get it from demo code and actual plan

    – jerik1
    7 hours ago








1




1





What exactly do you mean? This isn't clear for me

– George.Palacios
8 hours ago





What exactly do you mean? This isn't clear for me

– George.Palacios
8 hours ago













It's doing useless nested loop with #DocsItems table table scan. I know that in MS SQL Server CASE not always short-circuits - this is the example. I want to know if there is a way to rewrite this expression to short-circuit evaluation of this - always false - condition.

– jerik1
8 hours ago







It's doing useless nested loop with #DocsItems table table scan. I know that in MS SQL Server CASE not always short-circuits - this is the example. I want to know if there is a way to rewrite this expression to short-circuit evaluation of this - always false - condition.

– jerik1
8 hours ago















table scan happens if there are not enough rows for an index to make sense or no index also why sum if you exclude it in your where statement, if at all you better have a union where you merge 2 statements one with the sum and one exclude the sum and return 0 or null

– PPann
8 hours ago





table scan happens if there are not enough rows for an index to make sense or no index also why sum if you exclude it in your where statement, if at all you better have a union where you merge 2 statements one with the sum and one exclude the sum and return 0 or null

– PPann
8 hours ago




1




1





@PPann this is not the point of my question, sorry for being so unclear, don't know how to say it other way. I counted on you get it from demo code and actual plan

– jerik1
7 hours ago





@PPann this is not the point of my question, sorry for being so unclear, don't know how to say it other way. I counted on you get it from demo code and actual plan

– jerik1
7 hours ago










1 Answer
1






active

oldest

votes


















4


















What is currently happening



When running your query, the table scan, stream agg & compute scalar operators are not evaluated at runtime.



enter image description here



enter image description here





Why is it happening



The apply NL join means that for each row in #Docs, return a row from #Docsitems that matches the predicate. This predicate should be WHERE IDDocs = D.ID



But the compute scalar operator (EXPR1007) next to the select (the actual case statement) is calling the scalar function in the inner side of the NL apply (EXPR1005) only when Doctype <> 1. This as you know cannot happen, and they both return NULL.



Compute scalar between NL & SELECT:



enter image description here



Compute scalar on the inner side of the join:



enter image description here



This all seems to be due to how the CASE statement functions & removing literals. (difference between CASE 2 = 1 vs. CASE WHEN D.DocType <> 1)





Resolving



If you change the query to this:



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False


You should get the execution plan you desire:



enter image description here





Removing the SELonLOJ rule that is changing the plan on the rewrite.



Guessing



Reverting the rule that was applied to get closer to the CASE WHEN query can be done by adding the hint: OPTION( QUERYRULEOFF SELonLOJ )



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False
OPTION( QUERYRULEOFF SELonLOJ );


enter image description here



Showing the same situation (minus filter & left join) as the case statement, but the runtime elimination is not occuring.



enter image description here



&



enter image description here





Another rule that seems to get closer to the case when when turning it off is JoinPredNorm



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False
OPTION( QUERYRULEOFF JoinPredNorm )


With the filtering happening on the #Docs table as expected.



enter image description here






share|improve this answer





























  • never mind that there are no indexes and there only can be an table scan

    – PPann
    8 hours ago











  • @PPann - forget the indexes that is not the point

    – jerik1
    8 hours ago











  • @jerik1 I'll delete the answer for now since the question has shifted to how to remove it entirely.

    – Randi Vertongen
    7 hours ago















Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "182"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});















draft saved

draft discarded
















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f250784%2fhow-to-rewrite-case-expression-to-short-circuit-evaluation%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown


























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









4


















What is currently happening



When running your query, the table scan, stream agg & compute scalar operators are not evaluated at runtime.



enter image description here



enter image description here





Why is it happening



The apply NL join means that for each row in #Docs, return a row from #Docsitems that matches the predicate. This predicate should be WHERE IDDocs = D.ID



But the compute scalar operator (EXPR1007) next to the select (the actual case statement) is calling the scalar function in the inner side of the NL apply (EXPR1005) only when Doctype <> 1. This as you know cannot happen, and they both return NULL.



Compute scalar between NL & SELECT:



enter image description here



Compute scalar on the inner side of the join:



enter image description here



This all seems to be due to how the CASE statement functions & removing literals. (difference between CASE 2 = 1 vs. CASE WHEN D.DocType <> 1)





Resolving



If you change the query to this:



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False


You should get the execution plan you desire:



enter image description here





Removing the SELonLOJ rule that is changing the plan on the rewrite.



Guessing



Reverting the rule that was applied to get closer to the CASE WHEN query can be done by adding the hint: OPTION( QUERYRULEOFF SELonLOJ )



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False
OPTION( QUERYRULEOFF SELonLOJ );


enter image description here



Showing the same situation (minus filter & left join) as the case statement, but the runtime elimination is not occuring.



enter image description here



&



enter image description here





Another rule that seems to get closer to the case when when turning it off is JoinPredNorm



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False
OPTION( QUERYRULEOFF JoinPredNorm )


With the filtering happening on the #Docs table as expected.



enter image description here






share|improve this answer





























  • never mind that there are no indexes and there only can be an table scan

    – PPann
    8 hours ago











  • @PPann - forget the indexes that is not the point

    – jerik1
    8 hours ago











  • @jerik1 I'll delete the answer for now since the question has shifted to how to remove it entirely.

    – Randi Vertongen
    7 hours ago


















4


















What is currently happening



When running your query, the table scan, stream agg & compute scalar operators are not evaluated at runtime.



enter image description here



enter image description here





Why is it happening



The apply NL join means that for each row in #Docs, return a row from #Docsitems that matches the predicate. This predicate should be WHERE IDDocs = D.ID



But the compute scalar operator (EXPR1007) next to the select (the actual case statement) is calling the scalar function in the inner side of the NL apply (EXPR1005) only when Doctype <> 1. This as you know cannot happen, and they both return NULL.



Compute scalar between NL & SELECT:



enter image description here



Compute scalar on the inner side of the join:



enter image description here



This all seems to be due to how the CASE statement functions & removing literals. (difference between CASE 2 = 1 vs. CASE WHEN D.DocType <> 1)





Resolving



If you change the query to this:



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False


You should get the execution plan you desire:



enter image description here





Removing the SELonLOJ rule that is changing the plan on the rewrite.



Guessing



Reverting the rule that was applied to get closer to the CASE WHEN query can be done by adding the hint: OPTION( QUERYRULEOFF SELonLOJ )



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False
OPTION( QUERYRULEOFF SELonLOJ );


enter image description here



Showing the same situation (minus filter & left join) as the case statement, but the runtime elimination is not occuring.



enter image description here



&



enter image description here





Another rule that seems to get closer to the case when when turning it off is JoinPredNorm



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False
OPTION( QUERYRULEOFF JoinPredNorm )


With the filtering happening on the #Docs table as expected.



enter image description here






share|improve this answer





























  • never mind that there are no indexes and there only can be an table scan

    – PPann
    8 hours ago











  • @PPann - forget the indexes that is not the point

    – jerik1
    8 hours ago











  • @jerik1 I'll delete the answer for now since the question has shifted to how to remove it entirely.

    – Randi Vertongen
    7 hours ago
















4














4










4









What is currently happening



When running your query, the table scan, stream agg & compute scalar operators are not evaluated at runtime.



enter image description here



enter image description here





Why is it happening



The apply NL join means that for each row in #Docs, return a row from #Docsitems that matches the predicate. This predicate should be WHERE IDDocs = D.ID



But the compute scalar operator (EXPR1007) next to the select (the actual case statement) is calling the scalar function in the inner side of the NL apply (EXPR1005) only when Doctype <> 1. This as you know cannot happen, and they both return NULL.



Compute scalar between NL & SELECT:



enter image description here



Compute scalar on the inner side of the join:



enter image description here



This all seems to be due to how the CASE statement functions & removing literals. (difference between CASE 2 = 1 vs. CASE WHEN D.DocType <> 1)





Resolving



If you change the query to this:



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False


You should get the execution plan you desire:



enter image description here





Removing the SELonLOJ rule that is changing the plan on the rewrite.



Guessing



Reverting the rule that was applied to get closer to the CASE WHEN query can be done by adding the hint: OPTION( QUERYRULEOFF SELonLOJ )



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False
OPTION( QUERYRULEOFF SELonLOJ );


enter image description here



Showing the same situation (minus filter & left join) as the case statement, but the runtime elimination is not occuring.



enter image description here



&



enter image description here





Another rule that seems to get closer to the case when when turning it off is JoinPredNorm



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False
OPTION( QUERYRULEOFF JoinPredNorm )


With the filtering happening on the #Docs table as expected.



enter image description here






share|improve this answer
















What is currently happening



When running your query, the table scan, stream agg & compute scalar operators are not evaluated at runtime.



enter image description here



enter image description here





Why is it happening



The apply NL join means that for each row in #Docs, return a row from #Docsitems that matches the predicate. This predicate should be WHERE IDDocs = D.ID



But the compute scalar operator (EXPR1007) next to the select (the actual case statement) is calling the scalar function in the inner side of the NL apply (EXPR1005) only when Doctype <> 1. This as you know cannot happen, and they both return NULL.



Compute scalar between NL & SELECT:



enter image description here



Compute scalar on the inner side of the join:



enter image description here



This all seems to be due to how the CASE statement functions & removing literals. (difference between CASE 2 = 1 vs. CASE WHEN D.DocType <> 1)





Resolving



If you change the query to this:



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False


You should get the execution plan you desire:



enter image description here





Removing the SELonLOJ rule that is changing the plan on the rewrite.



Guessing



Reverting the rule that was applied to get closer to the CASE WHEN query can be done by adding the hint: OPTION( QUERYRULEOFF SELonLOJ )



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False
OPTION( QUERYRULEOFF SELonLOJ );


enter image description here



Showing the same situation (minus filter & left join) as the case statement, but the runtime elimination is not occuring.



enter image description here



&



enter image description here





Another rule that seems to get closer to the case when when turning it off is JoinPredNorm



SELECT
-- expression
SumAmount =
(SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID AND D.DocType <> 1 )

FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False
OPTION( QUERYRULEOFF JoinPredNorm )


With the filtering happening on the #Docs table as expected.



enter image description here







share|improve this answer















share|improve this answer




share|improve this answer








edited 5 hours ago

























answered 8 hours ago









Randi VertongenRandi Vertongen

10.2k3 gold badges13 silver badges35 bronze badges




10.2k3 gold badges13 silver badges35 bronze badges
















  • never mind that there are no indexes and there only can be an table scan

    – PPann
    8 hours ago











  • @PPann - forget the indexes that is not the point

    – jerik1
    8 hours ago











  • @jerik1 I'll delete the answer for now since the question has shifted to how to remove it entirely.

    – Randi Vertongen
    7 hours ago





















  • never mind that there are no indexes and there only can be an table scan

    – PPann
    8 hours ago











  • @PPann - forget the indexes that is not the point

    – jerik1
    8 hours ago











  • @jerik1 I'll delete the answer for now since the question has shifted to how to remove it entirely.

    – Randi Vertongen
    7 hours ago



















never mind that there are no indexes and there only can be an table scan

– PPann
8 hours ago





never mind that there are no indexes and there only can be an table scan

– PPann
8 hours ago













@PPann - forget the indexes that is not the point

– jerik1
8 hours ago





@PPann - forget the indexes that is not the point

– jerik1
8 hours ago













@jerik1 I'll delete the answer for now since the question has shifted to how to remove it entirely.

– Randi Vertongen
7 hours ago







@jerik1 I'll delete the answer for now since the question has shifted to how to remove it entirely.

– Randi Vertongen
7 hours ago





















draft saved

draft discarded



















































Thanks for contributing an answer to Database Administrators Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f250784%2fhow-to-rewrite-case-expression-to-short-circuit-evaluation%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown









Popular posts from this blog

Hudson River Historic District Contents Geography History The district today Aesthetics Cultural...

The number designs the writing. Feandra Aversely Definition: The act of ingrafting a sprig or shoot of one...

Ayherre Geografie Demografie Externe links Navigatiemenu43° 23′ NB, 1° 15′ WL43° 23′ NB, 1°...