Learn T-SQL With Erik: Memory Grants Intro
Chapters
- 00:00:00 – Introduction
- 00:03:44 – Memory Grants Overview
- 00:06:04 – Memory Grant Sharing
- 00:07:39 – String Columns and Memory Grants
- 00:10:23 – DOP and Memory Grants
Full Transcript
Erik monitoring tool mogul darling here with Darling Data. In today’s video, much like I think I foreshadowed in yesterday’s office hours video, we are going to talk about memory grants. We’re going to do a somewhat gentle introduction to them and then in the next video we’ll talk a little bit more about where they get interesting. I apologize for the state of my hair. It is very hot and humid here today. I’m starting to get weird, curly, I think my head is boiling at this point.
These hot lights that make the green screen effect possible are not helping. Anyway, down in the video description you will find pretty much everything you need in life. Period. I can’t imagine what else would go wrong.
If you want to hire me for consulting, you can do that. If you want to buy my training, you can do that. If you want to become a supporting member of this channel for as little as $4 a month, you can do that. If you want to ask me office hours questions, you can do that.
Quite frankly, food, clothing, and shelter are overrated. Pale in comparison to those things. And of course, if you find this channel has any value whatsoever to you in your life, you can always like, subscribe, and tell a friend.
It’s a pretty sweet thing for you to do. You can also, down in the old video description, you can get a hold of my free open source SQL Server monitoring tool. It does everything.
That you would ever want a performance monitoring tool to do. And more, probably. It monitors stuff like weight stats, blocking, deadlocks, top queries, all sorts of internal server metrics, CPU, memory, disk. You name it, it is in there. It covers the bases, baby.
It will even tell you about memory grants, which we’ll talk about today and tomorrow. And if you are having a good time embracing our robot companions, there are optional built-in MCP servers.
So you can have your robot friends look at your performance monitoring data and do some analysis on that. So you don’t have to go poking around through various charts and graphs and other sundry information that my monitoring tools expose. Right now, I only have two travel dates on the calendar.
That may change, depending on local factors. I will be at Data Saturday Croatia, June 12th and 13th. And I will be at PaaS Data Community Summit in Seattle, Washington, November 9th through 11th.
You can purchase tickets to my Advanced T-SQL Precon here, now. If you’re in the Croatian area and you’re watching my YouTube channel. It would be nice to see you in Croatia.
Have you ever had a Croatian hug from an American? We can have all that happen. But for now, May is May-ing along.
I don’t know where May is. I got the idea that it could have an 80-something and 90-degree day here in New York. But it doesn’t look like this here, right?
It looks more like the June image, which we’ll get to in just maybe about a week or so. But anyway, let’s talk about our… Let’s introduce memory grants, right?
So I’ve got query plans turned on here. Hold your horses, I know. And this is material that I’ve used in other videos. So if you’ve already seen this, perhaps you can just turn off the sound and watch me gesticulate and make faces for a while.
Maybe any one of those things would be fine for you. But I’ve written this query in sort of a silly-looking way. But the silly-looking reason…
The reason for this query looking silly-looking… Ah, that’s too many lookings. It will become obvious in a moment. If I run this query… And we look at the actual execution plan for this query, we will see that there is indeed a memory-consumering operator.
Ah, boy. This heat is boiling my brain and making me incapable of speech. There is a memory-consuming operator here, and that is a sort operator. Sorts require memory to write down their results in.
And if we hover over this select operator, we will see that this required 182 megs of memory in order to function. All right.
We’re just selecting 1,000 rows of an integer column and ordering it by reputation. We get 182 megs for that. Now, it is possible for SQL Server to share memory between operators in the same execution plan.
So what I have here is this query essentially twice, right? I am selecting this one and I am selecting this one, and I am joining them together on this ID column, right?
And when I do that, and we look at the execution plan, you might think to yourself, Eric, there are two sorts. There are two memory-consumering operators in this plan.
Surely, we will ask for double the memory, but we do not because there is a third memory-consuming operator in this plan, and that is this hash join.
And what this hash join is going to do is prevent both of these sorts from executing at the same time. All right. So that hash join is a blocking or a stop-and-go operator, meaning it has to absorb all of its results.
Technically, the sort is too, but the hash join is, it will be, all will be revealed in a moment. But the hash join is really where the magic is here because we have to stop and we have to build the hash table to use on the inner side of the join.
So this only asks for 183 megs of memory, so only one extra meg of memory, right? Because this sort runs and uses its memory, this hash join starts building its hash table, and then this part of the query plan in here runs, and this sort right here reuses that memory.
That this sort has shared with it. So all sorts of wonderful sharing things happen in this plan. We have the warm embrace of memory sharing within the query plan. But if I run this query with an inner loop join, right?
Inner loop joins are not stop-and-go operators. And so if we run this, we will get a slightly different looking execution plan, a rather different plan shape here, right?
We have nested loops instead. When it’s nested loops, like I said, are not blocking operators. They are not stop-and-go operators. So in this one, we ask for 364 megs of memory, which if you’ve got a sufficient number of fingers, you will come to the conclusion that 364 is indeed 182 times 2.
Or you could use addition for that as well, right? You could even use subtraction, and you could subtract 182 from 364.
There are myriad ways in which you can reverse engineer that problem. One of the biggest memory-grant villains in SQL Server, probably in databases in general, is, of course, strings.
Are, of course, strings. All strings. All strings must die. We should never have put them into databases. They cause nothing but problems.
And if you look over here, we’re sort of keyed. We have a little decoder tool. We have a little decoder chart here, where if we were to quote out these columns, I apologize to my loving fan base for having leading commas in this query.
I do. I would not do this unless there were an insanely practical reason for it. And that is, if we quote these out and back in, we will see the memory-grant grow as each column is introduced, sort of ending up with this about me column, ending up as a 10-gig or 11-gig memory-grant here.
I think it’s a little different right now, when this nvarchar max column is added in. And this is because SQL Server, when it’s estimating memory-grants for strings, it needs to sort of figure out how much string it’s going to deal with.
And what it does is it imagines that every single row for a string column is half full. So if we had a varchar 100, it would imagine that 50 bytes of it were full.
And this is probably a pretty good arrangement for most string columns, assuming that your developers are not lazy piles of so-and-so, and they have actually given your string columns a reasonable width.
If you have a varchar 8000 column that just says, like, state or a country in it, and it’s just like, you know, state abbreviations or country codes, you’re probably not going to be happy with your developers.
So if we run this query, and we wait for the query plan, and we look at the query plan, we will see that this query has asked for an 11-gigabyte memory-grant with all of those columns in there, almost as promised down here.
I guess SQL Server 2025 has added a gig to our memory-grant. One thing that is important to understand about memory-grants, though, is that memory-grants are not multiplied by a DOP by degree of parallelism in a parallel plan.
They are divided by DOP in a parallel plan. All query plans in SQL Server start as serial execution plans. And those serial execution plans, if they are chosen, if they become parallel plan candidates, and a parallel plan is chosen, SQL Server uses the memory-grant that it assigned to the serial plan for the parallel plan, but gives an equal portion, an equal share of memory, the warm embrace of DOP division to each thread, which can be good and bad.
It can be good if your queries have fairly even row distributions, but if your queries have very uneven row distributions, you may see certain threads spill and other threads not spill.
So here we have a parallel plan with a hash join in it, right here, doing essentially the same thing. If we hover over the select, we will see that this ran at degree of parallelism 8.
Now, I don’t want you to feel misled here. Remember the serial version of this plan asked for 182 megs of memory. We needed to add in a little bit here because the parallel exchange requires memory, right?
And all that other good stuff. The exchange buffers, those are memory-consuming things. So we needed a bit more memory. We needed about 15 megs more memory to do all of our parallel stuff, right?
We needed to distribute streams and gather streams and gather streams and well, you know, distribute streams and gather streams.
We had to do a lot of parallel exchanging and so we needed a little bit of extra memory to do that. All right. So in the next video, we’re going to talk a little bit more about memory grants, controlling them and other good stuff like that.
So thank you for watching. I hope you enjoyed yourselves. I hope you learned something. I hope that your brain is not boiling and it’s making you speak strangely. That’d be nice, right?
Anyway, good enough for now. Thank you for watching.
Going Further
If this is the kind of SQL Server stuff you love learning about, you’ll love my training. Blog readers get 25% off the Everything Bundle — over 100 hours of performance tuning content. Need hands-on help? I offer consulting engagements from targeted investigations to ongoing retainers. Want a quick sanity check before committing to a full engagement? Schedule a call — no commitment required.