Introduction to SQL Server Internals: How to Think Like the Engine
-
Upload
brent-ozar -
Category
Technology
-
view
16.255 -
download
2
Transcript of Introduction to SQL Server Internals: How to Think Like the Engine
![Page 1: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/1.jpg)
Intro to InternalsHow to Think Like the SQL
EngineBrent Ozar, Brent Ozar
Unlimited
![Page 2: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/2.jpg)
MIT License Copyright © 2016 Brent Ozar. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
![Page 3: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/3.jpg)
3
I know, I hate killing trees.
But having these next 3 pages in your hand will help a lot as we talk through the demos.
Print this 3-page PDF to follow along:http://u.BrentOzar.com/engine.pdf
![Page 4: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/4.jpg)
Brent OzarConsultant, Brent Ozar UnlimitedI make SQL Server faster and more reliable.
I created sp_Blitz® and the SQL Server First Responder Kit, and I loves sharing knowledge at BrentOzar.com. I hold a bunch of certifications and awards including the rare Microsoft Certified Master. You don’t care about any of that though.
Download the PDF: BrentOzar.com/go/enginepdf
/brentozar @brento brentozar
![Page 5: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/5.jpg)
Agenda
When you pass in a query, how does SQL Server build the results? Time to role play: Brent will be an end user sending in queries, and you will play the part of the SQL Server engine. Using simple spreadsheets as your tables, you will learn how SQL Server builds execution plans, uses indexes, performs joins, and considers statistics.
This session is for DBAs and developers who are comfortable writing queries, but not so comfortable when it comes to explaining nonclustered indexes, lookups, sargability, fill factor, and corruption detection.
![Page 6: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/6.jpg)
![Page 7: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/7.jpg)
![Page 8: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/8.jpg)
Index OR Data Rows
Slot Array
8KB
Page header
![Page 9: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/9.jpg)
Leaf pages
Indexpages
![Page 10: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/10.jpg)
![Page 11: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/11.jpg)
![Page 12: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/12.jpg)
![Page 13: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/13.jpg)
You: SQL Server.Me: end user.
![Page 14: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/14.jpg)
First query:SELECT IdFROM dbo.Users
![Page 15: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/15.jpg)
Your execution plan:1. Shuffle through all of the pages,
saying the Id of each record out loud.
![Page 16: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/16.jpg)
SQL Server’s execution plan
![Page 17: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/17.jpg)
SET STATISTICS IO ONLogical reads: the number of 8K pages we read.(79,672 x 8KB = 637MB)
![Page 18: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/18.jpg)
That’s 159 reams.
![Page 19: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/19.jpg)
Let’s add a filter.SELECT IdFROM dbo.UsersWHERE LastAccessDate > ‘2014/07/01’
![Page 20: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/20.jpg)
Your execution plan:1. Shuffle through all of the pages,
saying the Id of each record out loud,if their LastAccessDate > ‘2014/07/01’.
![Page 21: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/21.jpg)
SQL Server’s execution plan
![Page 22: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/22.jpg)
![Page 23: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/23.jpg)
Lesson:Using a WHERE without
a matching index means scanning all the data.
![Page 24: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/24.jpg)
![Page 25: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/25.jpg)
![Page 26: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/26.jpg)
Lesson:Estimated Subtree Cost guesses at CPU and IO
work required for a query.
![Page 27: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/27.jpg)
Let’s add a sort.SELECT IdFROM dbo.UsersWHERE LastAccessDate > ‘2014/07/01’ORDER BY LastAccessDate
![Page 28: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/28.jpg)
Your execution plan1. Shuffle through all of the pages,
writing down fields __________ for each record,if their LastAccessDate > ‘2014/07/01’.
2. Sort the matching records by LastAccessDate.
![Page 29: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/29.jpg)
SQL Server’s execution plan
![Page 30: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/30.jpg)
![Page 31: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/31.jpg)
Cost is up ~4xWe needed space towrite down our results,so we got a memory grant
Order By:
![Page 32: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/32.jpg)
![Page 33: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/33.jpg)
Memory is set when the query starts, and not revised.
SQL Server has to assume other people will run queries at the same time as you.
Your memory grant can change with each time that you run a query.
You can’t always get what you want.
![Page 34: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/34.jpg)
And if you run out of memory…
![Page 35: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/35.jpg)
Let’s get all the fields.SELECT *FROM dbo.UsersWHERE LastAccessDate > ‘2014/07/01’ORDER BY LastAccessDate
![Page 36: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/36.jpg)
Your execution plan1. Shuffle through all of the pages,
writing down fields __________ for each record,if their LastAccessDate > ‘2014/07/01’.
2. Sort the matching records by LastAccessDate.
![Page 37: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/37.jpg)
Lesson:SELECT * sucks.
But let’s dig deeper.
![Page 38: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/38.jpg)
Why does it suck?Do we work harder to read the data?Do we work harder to write the data?Do we work harder to sort the data?Do we work harder to output the data?
![Page 39: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/39.jpg)
SQL Server’s execution plan
![Page 40: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/40.jpg)
![Page 41: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/41.jpg)
SELECT ID SELECT *No order 66 66ORDER BY 259 20,666
![Page 42: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/42.jpg)
Lesson:Sorting is expensive,
and more fields makes it worse.
![Page 43: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/43.jpg)
Let’s run it a few times.SELECT *FROM dbo.UsersWHERE LastAccessDate > ‘2014/07/01’ORDER BY LastAccessDate;GO 5
![Page 44: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/44.jpg)
Your execution plan1. Shuffle through all of the pages,
writing down all the fields for each record,if their LastAccessDate > ‘2014/07/01’.
2. Sort the matching records by LastAccessDate.
3. Keep the output so you could reuse it the next time you saw this same query?
![Page 45: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/45.jpg)
Oracle can. (It better, since it costs
$47,000 per core.)
![Page 46: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/46.jpg)
SQL Server reads & sorts 5 times.
![Page 47: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/47.jpg)
Lesson:SQL Server caches raw data pages, not output.
![Page 48: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/48.jpg)
Nonclustered indexes: copies.Stored in the order we wantInclude the fields we wantCREATE INDEX IX_LastAccessDate_IdON dbo.Users(LastAccessDate, Id)
![Page 49: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/49.jpg)
Let’s go simple again.SELECT IdFROM dbo.UsersWHERE LastAccessDate > ‘2014/07/01’ORDER BY LastAccessDate;
![Page 50: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/50.jpg)
Your execution plan1. Grab IX_LastAccessDate and seek to
2014/07/01.2. Read the Id’s out in order.
![Page 51: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/51.jpg)
SQL Server’s execution plan
![Page 52: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/52.jpg)
![Page 53: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/53.jpg)
SELECT ID SELECT *No order 66 66ORDER BY 259 20,666ORDER BY(with index)
10 6,354
![Page 54: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/54.jpg)
![Page 55: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/55.jpg)
Lesson:Indexes reduce reads.
Duh.
![Page 56: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/56.jpg)
Lesson:Indexes also
reduce CPU time.
![Page 57: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/57.jpg)
Yes, this is a “seek.”
![Page 58: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/58.jpg)
Don’t think scan = terrible.
![Page 59: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/59.jpg)
It covers the fields we need in this query.But if we change the query…
That’s a covering index.
![Page 60: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/60.jpg)
Let’s add a couple of fields.SELECT Id, DisplayName, AgeFROM dbo.UsersWHERE LastAccessDate > ‘2014/07/01’ORDER BY LastAccessDate;
![Page 61: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/61.jpg)
One execution plan1. Grab IX_LastAccessDate_Id, seek to
2014/07/01.2. Write down the Id and LastAccessDate of
matching records.3. Grab the clustered index (white pages),
and look up each matching row by their Id to get DisplayName and Age.
![Page 62: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/62.jpg)
The SQL Server equivalent
![Page 63: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/63.jpg)
For simplicity, I told you I created this index with the Id.
SQL Server always includes your clustering keys whether you ask for ‘em or not because it has to join indexes.
That’s why SQL Server includes the key
![Page 64: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/64.jpg)
Key lookup is requiredwhen the index doesn’thave all the fields we need.Hover your mouse over thekey lookup and look for theOUTPUT fields.Small? Frequently used?Add ‘em to the index.DO NOT ADD A NEW INDEX.
Classic index tuning sign
![Page 65: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/65.jpg)
But to get that plan, I had to cheat.
![Page 66: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/66.jpg)
Because with 2014/07/01, I get:
![Page 67: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/67.jpg)
Lesson:Even with indexes,
there’s a tipping pointwhere scans work better.
![Page 68: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/68.jpg)
Enter statistics.
![Page 69: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/69.jpg)
Decide which index to useWhat order to process tables/indexes inWhether to do seeks or scansGuess how many rows will match your queryHow much memory to allocate for the query
Statistics help SQL Server:
![Page 70: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/70.jpg)
![Page 71: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/71.jpg)
WHERE LastAccessDate > ‘2014/07/01’
![Page 72: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/72.jpg)
Add it up, add it up
![Page 73: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/73.jpg)
![Page 74: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/74.jpg)
Automatic stats updates aren’t enough. Consider: • http://Ola.Hallengren.com• http://MinionWare.net/reindex Typical strategy: weekly statistics updatesUpdated statistics on an index invalidate query plans that involve that index• Affects your plan cache analysis• Can cause unpredictable query plan changes
Keep statistics updated.
![Page 75: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/75.jpg)
How about on a single random date?
![Page 76: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/76.jpg)
![Page 77: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/77.jpg)
![Page 78: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/78.jpg)
Let’s write it differently.
![Page 79: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/79.jpg)
Wait – what?
![Page 80: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/80.jpg)
Why can’t I get just one row
![Page 81: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/81.jpg)
Lesson:This is called
Cardinality Estimation,and it’s not just about
keeping stats updated.
![Page 82: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/82.jpg)
The Cardinality Estimator has huge improvements.
To turn ‘em on, just change your Compatibility Level.
Fortunately, SQL 2014/2016 fixes this.
![Page 83: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/83.jpg)
And run the exact same query again
![Page 84: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/84.jpg)
All better!
![Page 85: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/85.jpg)
Lesson:2014/2016’s new
Cardinality Estimatoris, uh, new
![Page 86: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/86.jpg)
Let’s add a join.
![Page 87: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/87.jpg)
![Page 88: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/88.jpg)
![Page 89: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/89.jpg)
![Page 90: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/90.jpg)
Lesson:bad cardinality
estimationis at the dark heartof many bad plans.
![Page 91: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/91.jpg)
Whew.That’s a lot of lessons.
![Page 92: Introduction to SQL Server Internals: How to Think Like the Engine](https://reader034.fdocuments.us/reader034/viewer/2022052116/5883d42f1a28abb7308b704d/html5/thumbnails/92.jpg)
Clustered indexes hold all the fields*Nonclustered indexes are light-weight* copies of the tableNC indexes reduce not just reads, but also CPU workSQL Server caches raw data pages, not query outputStatistics drive seek vs scan, index choice, memoryStatistics aren’t the only part: cardinality estimation mattersIncludes and seeks aren’t magically delicious
What we learned