Sample Header Ad - 728x90

Why does SQL Server not perform constant (UNION ALL) branch elimination with OPTION(RECOMPILE) when selecting the result into a scalar variable?

5 votes
2 answers
868 views
We use some 'aggregate' views to select from multiple tables using a discriminator (note: these views are *not* partitioned views, because the discriminator is not in the base tables). This normally works well when using option(recompile), as the query planner will *eliminate* the non-reachable union all paths before selection of a query plan. However, this constant-folding optimization appears defeated when selecting the result into a scalar variable. Selecting the result into a temporary table variable does not de-optimize the recompilation. Here is a reproduction case in SQL Server 2017: -- A table, don't need any data. create table [test].test_table (col1 int, primary key (col1)); -- A simple 'aggregate' view. Using the same table here is irrelevant and, -- while the view shows the scenario, it might not be required to reproduce the issue. create view [test].test_view as select col1, descrim = 1 from [test].test_table union all select col1, descrim = 2 from [test].test_table Normal query, which results in an optimized query plan touching only *one* of the union all branches: declare @descrim int = 2; select count(col1) from [test].test_view where descrim = @descrim option (recompile) -- explicit recompile here "works" However, as soon as a "select into scalar variable" is used, the plan becomes *de-optimized* as it does not eliminate the non-used union. (The plan is still correctly optimized when using a literal value in the query text.) declare @descrim int = 2; declare @brokeit int; select @brokeit = count(col1) from [test].test_view where descrim = @descrim option (recompile) -- explicit recompile here does NOT optimize plan for @descrim! **1. Is this de-optimization "expected"?** **2. Where is this *significant de-optimization* behavior with respect to option(recompile) and/or selecting into a scalar variable documented or otherwise discussed in depth?** **3. Is there an simple way to get an recompile-optimized plan with select @x = .. without using a temporary table (variable)?** While during query execution the union all will prevent actual IO access to the secondary artifact, such is still an issue with query plan generation. In the specific error case spawning this question, leaving in multiple tables for consideration prevents SQL Server from choosing an appropriate seek plan and the resulting plan options are very poor choices in the given domain. The first "good" plan: enter image description here The second and "bad" plan: enter image description here This "bad" plan also has an implicit conversion warning, making me suspect that the select into a scalar variable might be bypassing many different optimizations - or even ignoring the option(recompile) hint entirely.
Asked by user2864740 (205 rep)
Mar 8, 2021, 11:41 PM
Last activity: Apr 4, 2021, 03:59 PM