No partition elimination for partition column values in a lookup table?

This isn't available in the product for rowstore partitioned heaps. If you change the table to have a partitioned clustered columnstore index then you will sometimes be able to eliminate partitions via rowgroup elimination by a bitmap filter, which seems to be what you're after.

I blogged about this here. Quoting a small section:

We know that based on the data in the dimension table that SQL Server only needs to read two partitions from the fact table. Could the query optimizer in theory do better than it did? Consider the fact that a partitioned table has at most 15000 partitions. All of the partition values cannot overlap and they don’t change without a DDL operation. When building the hash table the query optimizer could keep track of which partitions have at least one row in them. By the end of the hash build we’ll know exactly which partitions could contain data, so the rest of the partitions could be skipped during the probe phase.

Perhaps this isn’t implemented because it’s important for the hash build to be independent of the probe. Maybe there’s no guarantee available at the right time that the bitmap operator will be pushed all the way down to the scan as opposed to a repartition streams operator. Perhaps this isn’t a common case and the optimization isn’t worth the effort. After all, how often do you join on the partitioning column instead of filtering by it?


Just for completeness, you can get dynamic partition elimination, but only if the join type is nested loops with correlated parameters.

For example, using the provided partitioning function and scheme:

CREATE PARTITION FUNCTION MonthlyPartition ([date])
AS RANGE RIGHT FOR VALUES
(
    '20190201', '20190301', '20190401',
    '20190501', '20190601', '20190701', '20190801', 
    '20190901', '20191001', '20191101', '20191201'
);

CREATE PARTITION SCHEME MonthWisePartition
AS PARTITION MonthlyPartition ALL TO ([PRIMARY]);

and tables:

CREATE TABLE dbo.PartitionResearch 
(
    tranid integer identity(1,1) NOT NULL,
    [Date] date NULL,
    Account integer NULL,
    SeqNumber tinyint NULL,
    AlertType integer NULL,
    IsFirst tinyint NULL,
    Indicator1 integer NULL,
    [time] time NULL
)
ON MonthWisePartition([Date]);

CREATE TABLE dbo.MonthLookup
(
    [MonthId] integer IDENTITY(1,1) NOT NULL,
    [Date] date NOT NULL
)
ON [PRIMARY];

The query that did not use partition elimination:

SELECT
    a.* 
FROM dbo.PartitionResearch AS a
JOIN dbo.MonthLookup AS b
    ON a.[Date]=b.[Date]
WHERE
    a.Account IN (1000000,2000000);

...produces the following plan:

nested loops plan

The properties of the PartitionResearch table scan show dynamic partition elimination using the current date from the MonthLookup table on each iteration of the loop:

Dynamic partition elimination

That option is preferred here because the tables are empty. In your case the optimizer preferred a hash join plan for estimated cost reasons. Given a MonthLookup table with 56 rows (as shown in your plans), the nested loops alternative would scan a single partition 56 times. The optimizer (probably rightly) assesses that it would be better to scan all 12 partitions once instead.

If you want to test your data with dynamic partition elimination, you may get such a plan with an OPTION (LOOP JOIN) query hint. With only two partitions accessed by the example query, it is at least plausible that two partitions could be scanned 28 times each in reasonable time.

For a more robust general strategy, you would need to write specific T-SQL to achieve partition elimination, for example using the $PARTITION function, a temporary table, or dynamic SQL.