Quantcast
Channel: Erik Darling – Brent Ozar Unlimited®
Viewing all articles
Browse latest Browse all 370

Filtered Indexes vs Parameterization (Again)

$
0
0

At First I Was Like…

This won’t work at all, because parameters are a known enemy of filtered indexes. But it turns out that some filtered indexes can be used for parameterized queries, whether they’re from stored procedures, dynamic SQL, or in databases with forced parameterization enabled.

Unfortunately, it seems limited to filtering out NULLs rather than exact values.

Easy Example

If I set up this proc and index, and then run it, it’ll use the filtered index even though it seems like it maybe shouldn’t.

CREATE OR ALTER PROCEDURE dbo.filter_check (@age INT, @creation_date DATETIME)
AS
BEGIN
    SELECT COUNT(*) AS records
    FROM dbo.Users AS u
    WHERE u.Age >= @age
    AND u.CreationDate >= @creation_date;
END

CREATE INDEX ix_whatever ON dbo.Users(CreationDate) INCLUDE(Age) WHERE Age IS NOT NULL;

EXEC dbo.filter_check @age = 18, @creation_date = '2017-10-18';

wakka wakka

Even if I pass in a NULL for @age, it works. If I were searching for IS NULL or IS NOT NULL, well, that wouldn’t work, but that’s also pretty tough to parameterize. Heh.

Horse Water

This really only helps if you have a parameterized predicate on a column with a good chunk of NULL values in it. You can bypass indexing, and queries needing to navigate all those NULL values, with a filtered index.

But if you want to do something more specific, things don’t work as well. Using a slightly different example, with forced parameterization, this doesn’t work.

ALTER DATABASE StackOverflow2013 SET PARAMETERIZATION FORCED;

CREATE INDEX ix_votes_filtered_too
    ON dbo.Votes(VoteTypeId) 
        WHERE VoteTypeId = 9;

SELECT COUNT(*)
FROM dbo.Votes AS v
WHERE v.VoteTypeId = 9;

The query plan will skip our filtered index, and warn about it in the select operator properties — just hit F4 to bring those up.

Letdown

Other People’s F4

Neck Pain

If you’re one of those crazy kids who lets NULLs walk all over their data, you might find some performance gains by filtering them out of your indexes, but only if they make up a good chunk of your data.

This is also a bummer for people who rely on forced parameterization to help deal with other issues — it takes a potentially really powerful tool out of your arsenal for query and index tuning.

Thanks for reading!


Viewing all articles
Browse latest Browse all 370

Latest Images

Trending Articles



Latest Images