Nausea
Okay, deep breath. Deep, deep breath.
Would you believe I still have to fix queries with a bunch of functions in joins and where clauses? Like every day? All day?
Where things get tough is when there’s some third party vendor app where code can’t be changed, but customers have become so fed up with performance that they’re willing to make other changes to help things along.
This isn’t a big fireworks demo. I could have spent a lot more time finding a worse scenario, and I’ve hinted it to exacerbate the issue a bit.
Sometimes my hardware is too good for bad demos, probably because it’s not in the cloud.
That whole “cloud” thing has some real problems.
Setup
Anyway, let’s say we have this index (because we do, I just created it).
CREATE INDEX p ON dbo.Posts (CommunityOwnedDate, Score) WITH (SORT_IN_TEMPDB = ON, DATA_COMPRESSION = PAGE); GO
Let’s further presume that we have this stored procedure.
This stored procedure could have been a query.
CREATE OR ALTER PROCEDURE dbo.FixNonSargable ( @CommunityOwnedDate datetime, @Score integer ) AS BEGIN SET NOCOUNT, XACT_ABORT ON; SELECT p.* FROM dbo.Posts AS p WHERE COALESCE(p.CommunityOwnedDate, '17530101') >= @CommunityOwnedDate AND p.Score >= @Score ORDER BY p.Id DESC OPTION ( USE HINT('QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_140'), /*No batch mode*/ MAXDOP 1 /*No parallelism*/ ); END; GO
When executed with such great gusto, it’s a bit slow.
EXEC dbo.FixNonSargable @CommunityOwnedDate = '20130101', @Score = 10;
At ~1.4 seconds, we’re very upset with performance. Throw the whole thing in the trash. Install DuckDB.
Index Reversal
If we change the key column order of our index, so the column with a seekable predicate can go first, we can get faster query execution.
CREATE INDEX p ON dbo.Posts (Score, CommunityOwnedDate) WITH (SORT_IN_TEMPDB = ON, DATA_COMPRESSION = PAGE, DROP_EXISTING = ON); GO
Now you don’t have to wait 6-never months for your vendor to fix their garbage code.
In this case, changing the order of key columns was a more beneficial arrangement for this particular query.
Results may vary. Not query results! I mean like, if you go do this in your database. On “your” hardware. In the “cloud”.
Thanks for reading!
Going Further
If this is the kind of SQL Server stuff you love learning about, you’ll love my training. I’m offering a 75% discount to my blog readers if you click from here. I’m also available for consulting if you just don’t have time for that, and need to solve database performance problems quickly. You can also get a quick, low cost health check with no phone time required.
One thought on “Indexing SQL Server Queries For Performance: Fixing A Non-SARGable Predicate”
Comments are closed.