>implying
Way back when, I posted about turning the Votes table in the Stack Overflow database into a Partitioned View.
While working on related demos recently, I came across something kind of cool. It works for both partitioned tables and views, assuming you’ve done some things right.
In this example, both versions of the table are partitioned in one year chunks on the CreationDate column.
That means when I run queries like this, neither one is eligible for partition elimination.
Why? Because the CreationDate column in the Posts table could have any range of dates at all in it, so we need to query every partition for matches.
SELECT COUNT(*) AS records FROM dbo.Votes AS v JOIN dbo.Posts AS p ON p.Id = v.PostId AND p.CreationDate = v.CreationDate; SELECT COUNT(*) AS records FROM dbo.AllVotes AS v JOIN dbo.Posts AS p ON p.Id = v.PostId AND p.CreationDate = v.CreationDate;
How do we know that? Well, for the partitioned table, because all 12 partitions were scanned.
For the partitioned view, well…
I think it’s obvious what’s gone on here.
Eliminationist
Are you ready for the cool part?
If I add a predicate to the JOIN (or WHERE clause) for the Posts table (remember that the Votes table is partitioned, and the Posts table isn’t), SQL Server is so smart, it can use that to trim the range of partitions that both queries need to access.
SELECT COUNT(*) AS records FROM dbo.Votes AS v JOIN dbo.Posts AS p ON p.Id = v.PostId AND p.CreationDate = v.CreationDate AND p.CreationDate >= '20140101'; SELECT COUNT(*) AS records FROM dbo.AllVotes AS v JOIN dbo.Posts AS p ON p.Id = v.PostId AND p.CreationDate = v.CreationDate AND p.CreationDate >= '20140101';
The partitioned table plan eliminates 8 partitions, and the seek predicate is converted to the Votes table.
And the partitioned view is also smart enough to pick up on that and only scan the partitions I need.
Expected?
Logically, it makes total sense for this to happen. The optimizer is pretty smart, so this works out.
Thanks for reading!