I have a question about this query plan.
We have a table in a test environment, Order_Details_Taxes, that has 11,225,799 rows. This table has a column, OrdTax_PLTax_LoadDtl_Key, which is NULL on every single row. This test environment is configured in such a way that this column will always be NULL. There is an index on this column.
I ran some queries against this table using a NULL value for a column. A NULL INNER JOIN will never yield any results.
declare @Keys table (KeyValue decimal(15,0))
insert into @Keys (KeyValue) values (null)
select OrdTax_PLTax_LoadDtl_Key
from @Keys
inner join Order_Details_Taxes
on OrdTax_PLTax_LoadDtl_Key = KeyValue
select *
from @Keys
inner join Order_Details_Taxes
on OrdTax_PLTax_LoadDtl_Key = KeyValue
These are the first queries in the query plan. The first select
starts from the hundred-million-row table and joins to @Keys. The second select
starts from @Keys, but it does a clustered index scan on this table.
I know temporary @Tables are questionable in most cases, so I changed my query to use a temporary #Table:
if object_id ('tempdb..#Keys') is not null
drop table #Keys
create table #Keys (KeyValue decimal(15,0))
insert into #Keys (KeyValue) values (null)
select OrdTax_PLTax_LoadDtl_Key
from #Keys
inner join Order_Details_Taxes
on OrdTax_PLTax_LoadDtl_Key = KeyValue
select *
from #Keys
inner join Order_Details_Taxes
on OrdTax_PLTax_LoadDtl_Key = null
These queries were optimized and ran exactly as I expected-- get the #Keys NULL value first and seek to Order_Details_Taxes. They are the last queries in the query plan linked.
Why do the queries in which I used a @Table variable perform index and table scans on this large table, when I am joining using from a table that has a single NULL value to a table with only NULLs in this key value?
I assume the answer is statistics and/or cardinality limitations of @Table variables, but the resulting query plan was non-intuitive to me.
ANSI_NULLs
is on for this table and my SQL session.