When you sit down to choose data types, max really should be last on your list. There are very few legitimate uses for them.
Start by asking yourself if someone may ever throw in a string over 4000 or 8000 characters, you’re storing XML or JSON, or some other foolish endeavor.
If the answer is “no”, or “just to be safe“, stop right there. Put that max datatype down. You’re really gonna hate when they end up doing to your memory grants.
But you’ll also hate what they do to queries that try to filter on them.
No matter how much you scream, holler, and curse, when you try to filter data in a column with a max type, that predicate can’t be pushed to when you touch the index.
Leaving aside that max data types can’t be in the key of an index, because that would be insane, even if you stick them in the includes you’re looking at a lot of potential bulk, and not the good kind that makes you regular.
Let’s look at these two queries. The first one hits the Body column, and the second one hits the Title column.
SELECT c = COUNT_BIG(*) FROM dbo.Posts AS p WHERE p.Body = N'A'; SELECT c = COUNT_BIG(*) FROM dbo.Posts AS p WHERE p.Title = N'A';
Both of these queries suck because we have to scan the entire Posts table, but at least the second one would be indexable if we cared enough to add one.
Starting off clear: This will happen regardless of if your search argument is a variable or a parameter, regardless of recompile hints.
DECLARE @A nvarchar(MAX) = N'A'; SELECT c = COUNT_BIG(*) FROM dbo.Posts AS p WHERE p.Title = @A; GO DECLARE @A nvarchar(MAX) = N'A'; SELECT c = COUNT_BIG(*) FROM dbo.Posts AS p WHERE p.Title = @A OPTION(RECOMPILE); GO
I see this quite often in ORMs where people don’t explicitly define datatypes, and stored procedures where people are being daft.
This is the sort of stuff you have to deal with when you use max data types.
They really are a pain, and the larger your tables are, the harder it can be to make changes later. Add in any sort of data synchronization and it all gets much worse.
In tomorrow’s post, we’ll look at how user defined functions can make things horrible.
Thanks for reading!