+ All Categories
Home > Technology > Why Defragmenting Your Indexes Isn't Helping

Why Defragmenting Your Indexes Isn't Helping

Date post: 22-Jan-2018
Category:
Upload: brent-ozar
View: 2,922 times
Download: 3 times
Share this document with a friend
98
Why Defragmenting Your Indexes Isn’t Helping
Transcript
Page 1: Why Defragmenting Your Indexes Isn't Helping

Why Defragmenting Your Indexes Isn’t Helping

Page 2: Why Defragmenting Your Indexes Isn't Helping

99-05: dev, architect, DBA

05-08: DBA, VM, SAN admin

08-10: MCM, Quest Software

Since: consulting DBA

www.BrentOzar.com

[email protected]

Free conference: GroupBy.org

sp_Blitz: FirstResponderKit.org

SQLServerUpdates.com

PasteThePlan.com

Github.com/BrentOzar

Personal blog: Ozar.me

Page 3: Why Defragmenting Your Indexes Isn't Helping

You’re here because

performance sucks.

Page 4: Why Defragmenting Your Indexes Isn't Helping

Success means

a performance boost

that end users notice.

Page 5: Why Defragmenting Your Indexes Isn't Helping

The two kinds of fragmentation

Why the fix makes things worse

The better performance fix

When people insist on rebuilds

What to do in overnight windows

This deck: BrentOzar.com/go/defrag

“Fragmentation sucks.”

Page 6: Why Defragmenting Your Indexes Isn't Helping

Page Header

Index OR

Data Rows

Slot Array

8KBData is stored

in 8KB pages.

Page 7: Why Defragmenting Your Indexes Isn't Helping
Page 8: Why Defragmenting Your Indexes Isn't Helping

Hall - Loggins Loggins -

MessinaMessina -

Oates

In a freshly rebuilt index, the 8K pages are full, and let’s say

they’re all in order on disk.

Location 4096 Location 4097 Location 4098

Page 9: Why Defragmenting Your Indexes Isn't Helping

Hall - Loggins

He needs to go

here, but there’s

no empty space.

Loggins -

MessinaMessina -

Oates

McDonald, Michael moves to our town.

Page 10: Why Defragmenting Your Indexes Isn't Helping

Split! New

Location 4096 Location 4097 Location 9144 Location 4098

Page split!SQL allocates another

page.

But it won’t be in

physical order.

Page 11: Why Defragmenting Your Indexes Isn't Helping

Split! New

Location 4096 Location 4097 Location 9144 Location 4098

There are two kinds of fragmentation here.

Page 12: Why Defragmenting Your Indexes Isn't Helping

Monitoring this stuff

To track page splits:

Perfmon counter SQL Server:Access Methods – Page Splits/sec

To track external fragmentation:

sys.dm_db_index_physical_stats – avg_fragmentation_in_percent

To track internal fragmentation:

sys.dm_db_index_physical_stats – avg_page_space_used_in_percent

Page 13: Why Defragmenting Your Indexes Isn't Helping

Great! I’ll monitor for

page splits.

Page 14: Why Defragmenting Your Indexes Isn't Helping

Create an empty table

CREATE TABLE TheHeart

(ID INT IDENTITY(1,1)

PRIMARY KEY CLUSTERED,

Groove VARCHAR(100));

GO

Page 15: Why Defragmenting Your Indexes Isn't Helping

Check your page splits

SELECT * FROM

sys.dm_os_performance_counters

WHERE counter_name LIKE '%Splits%’;

Page 16: Why Defragmenting Your Indexes Isn't Helping

Insert just one row

INSERT INTO dbo.TheHeart

(Groove)

VALUES ('The chills that you spill

up my back keep me filled');

GO

Page 17: Why Defragmenting Your Indexes Isn't Helping

Check your page splits again

SELECT * FROM

sys.dm_os_performance_counters

WHERE counter_name LIKE '%Splits%’;

Page 18: Why Defragmenting Your Indexes Isn't Helping

Adding a

new page

is also called

a page split.

Page 19: Why Defragmenting Your Indexes Isn't Helping

Monitoring this stuff

To track page splits:

Perfmon counter SQL Server:Access Methods – Page Splits/sec

There are other more accurate ways to monitor page splits, but if this lying thing came as a

surprise to you, buckle up. It’s about to get worse.

To track external fragmentation:

sys.dm_db_index_physical_stats – avg_fragmentation_in_percent

To track internal fragmentation:

sys.dm_db_index_physical_stats – avg_page_space_used_in_percent

Page 20: Why Defragmenting Your Indexes Isn't Helping

Is external fragmentation bad?

Page 21: Why Defragmenting Your Indexes Isn't Helping

Pop quiz: if your pages are out of order

Will your maintenance tasks take longer?

(Backups, index & stats maintenance, CHECKDB)

Will queries reading from RAM be slower?

Will queries reading from disk be slower?

• What if you’re seeking?

• What if you’re scanning?

How do you fix it?

Page 22: Why Defragmenting Your Indexes Isn't Helping

Pop quiz: if your pages are out of order

Will your maintenance tasks take longer?

(Backups, index & stats maintenance, CHECKDB)

Will queries reading from RAM be slower?

Will queries reading from disk be slower?

• What if you’re seeking?

• What if you’re scanning?

How do you fix it?

Page 23: Why Defragmenting Your Indexes Isn't Helping

Systems Performance by Brendan Gregg

Page 24: Why Defragmenting Your Indexes Isn't Helping

Systems Performance by Brendan Gregg

Page 25: Why Defragmenting Your Indexes Isn't Helping

Systems Performance by Brendan Gregg

Page 26: Why Defragmenting Your Indexes Isn't Helping

Pop quiz: if your pages are out of order

Will your maintenance tasks take longer?

(Backups, index & stats maintenance, CHECKDB)

Will queries reading from RAM be slower?

Will queries reading from disk be slower?

• What if you’re seeking?

• What if you’re scanning?

How do you fix it?

Page 27: Why Defragmenting Your Indexes Isn't Helping

Fixing out-of-order pages

Reorganize Rebuild

What does it do? Shuffles individual pages around,

around, one at a time

Builds a whole new

copy of the index

Are all pages in physical order when

when we’re done?

No Maybe, but only if you use MAXDOP

MAXDOP 1

Can it be done online? Yes Enterprise Edition only

Can it be interrupted? Yes, and your

progress is kept

No

Is it a logged operation? Yes Yes

Does it slow down mirrors, AGs, log

AGs, log shipping?

Yes Yes

Page 28: Why Defragmenting Your Indexes Isn't Helping

Users hate your

“fix.”

Page 29: Why Defragmenting Your Indexes Isn't Helping

Pop quiz: if your pages are out of order

Will your maintenance tasks take longer?

(Backups, index & stats maintenance, CHECKDB)

Will queries reading from RAM be slower?

Will queries reading from disk be slower?

• What if you’re seeking?

• What if you’re scanning?

How do you fix it?

Page 30: Why Defragmenting Your Indexes Isn't Helping

Wait! I’ll set FILL

FACTOR!

Data

Page 31: Why Defragmenting Your Indexes Isn't Helping

Hall - Loggins

He needs to go

here, but there’s

no empty space.

Loggins -

MessinaMessina -

Oates

McDonald, Michael moves to our town.

Page 32: Why Defragmenting Your Indexes Isn't Helping

Fill factor leaves empty space on the page.

Default set at the server level: 100% (and 0 means the same thing)

So the idea is:

• Set fill factor to something lower (like 70-80)

• Leave empty space on every page

• When new records are added, we’ll have space

so we don’t need to split pages

Let’s see a couple examples.

Data

Page 33: Why Defragmenting Your Indexes Isn't Helping

dbo.Users

Clustered

index on ID

Users are ordered by ID, an

identity field

Do you want empty space

on this page?

• Inserts?

• Updates?

• Deletes?

What’s the right fill factor?

Page 34: Why Defragmenting Your Indexes Isn't Helping

dbo.Usersnon-clustered on

LastAccessDate

Users are ordered by the last date they visited Stack Overflow

Do you want empty space on this page?

• Inserts?

• Updates?

• Deletes?

What’s the right fill factor?

Page 35: Why Defragmenting Your Indexes Isn't Helping

The default fill factor of

100% keeps your database

small.

Page 36: Why Defragmenting Your Indexes Isn't Helping

When you set fill factor <>

100%, guess what you’re really

doing.

Page 37: Why Defragmenting Your Indexes Isn't Helping

When you set fill factor <>

100%, guess what you’re really

doing.

“Does that make me

a data scientist?”

Page 38: Why Defragmenting Your Indexes Isn't Helping

Internal fragmentation

That’s right: setting fil l factor <> 100% actually causes …

Page 39: Why Defragmenting Your Indexes Isn't Helping

Pop quiz: if your pages have empty space

Will your maintenance tasks take longer?

(Backups, index & stats maintenance, CHECKDB)

Will queries reading from RAM be slower?

Will queries reading from disk be slower?

• What if you’re seeking?

• What if you’re scanning?

How do you fix it?Data

Page 40: Why Defragmenting Your Indexes Isn't Helping

Data

Pop quiz: if your pages have empty space

Will your maintenance tasks take longer?

(Backups, index & stats maintenance, CHECKDB)

Will queries reading from RAM be slower?

Will queries reading from disk be slower?

• What if you’re seeking?

• What if you’re scanning?

Page 41: Why Defragmenting Your Indexes Isn't Helping

THE PROBLEM IS US.External fragmentation doesn’t really matter

But to “fix” it, we’ve been:

• Rebuilding/reorging our indexes daily,

which actually makes some things worse

• Setting fill factor, which

causes internal fragmentation

And internal fragmentation DOES matter

(and we’ve been the ones causing it all along!)

Page 42: Why Defragmenting Your Indexes Isn't Helping
Page 43: Why Defragmenting Your Indexes Isn't Helping

SQL Server needs a dog.

Page 44: Why Defragmenting Your Indexes Isn't Helping

The two kinds of fragmentation

Why the fix makes things worse

The better performance fix

When people insist on rebuilds

What to do in overnight windows

This deck: BrentOzar.com/go/defrag

I’m so confused.

Page 45: Why Defragmenting Your Indexes Isn't Helping

The short answer

1. Set fill factor at the server level back to 100%.

2. Use sp_Blitz and sp_BlitzIndex to check for index fill factors <80%, and set those

back up to 80% or higher (or 100%).

3. Rebuild your indexes once to atone for those past sins,

getting them back up to 100% fill factor.

4. Monitor the right metric,

and use the scientific method to improve it.

Page 46: Why Defragmenting Your Indexes Isn't Helping

How SQL Server Schedules CPU

What’s Running Now What’s Waiting (Queue)

Page 47: Why Defragmenting Your Indexes Isn't Helping

How SQL Server Schedules CPU

What’s Running Now

SELECT * FROM

dbo.Restaurants

(By Brent)

What’s Waiting (Queue)

Page 48: Why Defragmenting Your Indexes Isn't Helping

How SQL Server Schedules CPU

What’s Running Now

SELECT * FROM

dbo.Restaurants

(By Brent)

What’s Waiting (Queue)

SELECT * FROM dbo.Tattoos

(By Jeremiah)

SELECT * FROM dbo.Rabbits

(By Kendra)

Page 49: Why Defragmenting Your Indexes Isn't Helping

How SQL Server Schedules CPU

What’s Running Now

SELECT * FROM

dbo.Restaurants

(By Brent)

What’s Waiting (Queue)

SELECT * FROM dbo.Tattoos

(By Jeremiah)

SELECT * FROM dbo.Rabbits

(By Kendra)

Page 50: Why Defragmenting Your Indexes Isn't Helping

How SQL Server Schedules CPU

What’s Running Now What’s Waiting (Queue)

SELECT * FROM dbo.Tattoos(By Jeremiah)

SELECT * FROM dbo.Rabbits(By Kendra)

SELECT * FROM dbo.Restaurants(By Brent)

Page 51: Why Defragmenting Your Indexes Isn't Helping

SQL Server Waits For:

Resources:

CPU, memory, storage, network, latches, locks

Stuff outside of SQL Server (Preemptive):

COM, OLEDB, CLR

System Tasks:

Lazywriter, trace, full text search

Page 52: Why Defragmenting Your Indexes Isn't Helping

Is this SQL Server working hard?

What’s Running Now

SELECT * FROM

dbo.Restaurants

(By Brent)

What’s Waiting (Queue)

Page 53: Why Defragmenting Your Indexes Isn't Helping

What about now?

What’s Running Now

SELECT * FROM

dbo.Restaurants

(By Brent)

What’s Waiting (Queue)

SELECT * FROM dbo.Tattoos

(By Jeremiah)

SELECT * FROM dbo.Rabbits

(By Kendra)

Page 54: Why Defragmenting Your Indexes Isn't Helping

Or now?

What’s Running Now

SELECT * FROM

dbo.Restaurants

(By Brent)

What’s Waiting (Queue)

SELECT * FROM dbo.Tattoos(By Jeremiah)

SELECT * FROM dbo.Rabbits(By Kendra)

EXEC sp_WhoIsActive(By Adam Machanic)

BACKUP DATABASE SQLbits(By Ola Hallengren)

DBCC CHECKDB(By Paul Randal)

Page 55: Why Defragmenting Your Indexes Isn't Helping

Some queries are simple

Page 56: Why Defragmenting Your Indexes Isn't Helping

Some queries have a lot going on

Page 57: Why Defragmenting Your Indexes Isn't Helping

These were simple little queries.

What’s Running Now

SELECT * FROM

dbo.Restaurants

(By Brent)

What’s Waiting (Queue)

SELECT * FROM dbo.Tattoos

(By Jeremiah)

SELECT * FROM dbo.Rabbits

(By Kendra)

Page 58: Why Defragmenting Your Indexes Isn't Helping

But one query looks more like this:

What’s Running Now

Index scan of Table1

What’s Waiting (Queue)

Index scan of Table2

Index scan of Table3

Index scan of Table4

Page 59: Why Defragmenting Your Indexes Isn't Helping

So for each core, you’ll likely see:

What’s Running Now

One task running,

using CPU

What’s Waiting (Queue)

Several

(or several DOZEN) tasks

stacked up waiting on stuff

Page 60: Why Defragmenting Your Indexes Isn't Helping

If we do this for one second,

how many seconds of waits?

What’s Running Now

One task running,

using CPU

What’s Waiting (Queue)

15 tasks waiting on storage

3 tasks waiting on locks

1 task waiting on CPU

Page 61: Why Defragmenting Your Indexes Isn't Helping

Hours of wait time per hour

0

5

10

15

20

25

30

6:00 7:00 8:00 9:00 10:00 11:00

CPU

Locks

Storage

Page 62: Why Defragmenting Your Indexes Isn't Helping

How hard is your server working?

Dynamic Management View (DMV) sys.dm_os_wait_stats

Tracked cumulatively over time

Trend on an hourly basis and break it out by:•Weekday vs weekend

•Business hours vs after hours

•Maintenance windows (backups, DB maintenance)

Page 63: Why Defragmenting Your Indexes Isn't Helping

When Wait Time changes

This metric is linked to Batch Requests:the more work the server is asked to do, the more it waits.

Going up? Batch Requests could be going up, or the server is responding slower to the existing workload.

• Storage got slower, indexes were dropped, queries were tuned poorly, other processes are running on the server

Going down? Batch Requests could be too, or server is responding faster to the workload.

• Indexes or queries were tuned, more memory was added

Page 64: Why Defragmenting Your Indexes Isn't Helping

Wait Time per core per hour

Near zero – Your server isn’t doing anything.

(Although that doesn’t mean every query is fast.)

1 hour of waits – You’re still not doing much.

Multiple hours per core – now we’re working!

And we should probably be tuning.

Page 65: Why Defragmenting Your Indexes Isn't Helping

Free script: sp_BlitzFirst

Totally free open source diagnostic tool.

Installs in the master by default, but can go anywhere.

Runs in 5 seconds ideally, but can be more under load.

By default, shows waits for a 5-second sample now.

@SinceStartup = 1 shows waits since, uh, startup.

Page 66: Why Defragmenting Your Indexes Isn't Helping

Typical output under load

Page 67: Why Defragmenting Your Indexes Isn't Helping

Most useful parameters

@SinceStartup = 1

@ExpertMode = 1

@Seconds = 60

@OutputDatabaseName = ‘DBAtools’,@OutputSchemaName = ‘dbo’,@OutputTableName = ‘BlitzFirstResults’

Page 68: Why Defragmenting Your Indexes Isn't Helping

Solve the emergencies,

then focus on waits, in order.

Some waits are like poison:

any occurrences of them have to be fixed first.

After that, work through the list.

You’ll never make them go away,

but you have to focus on them in order.

Page 69: Why Defragmenting Your Indexes Isn't Helping

Wait stats decoder ring

Wait type Means sp_BlitzCache

@SortOrder =

CXPACKET Parallelism Reads, CPU

LCK* Blocking locks Duration, reads

PAGEIOLATCH Reading data from data files Reads

SOS_SCHEDULER_YIELD Waiting for CPU time (via CPU

schedulers)

CPU

RESOURCE_SEMAPHORE Query needs memory in order to

start

Memory grant

Page 70: Why Defragmenting Your Indexes Isn't Helping

The two kinds of fragmentation

Why the fix makes things worse

The better performance fix

When people insist on rebuilds

What to do in overnight windows

This deck: BrentOzar.com/go/defrag

What if someone

wants to play doctor?

Page 71: Why Defragmenting Your Indexes Isn't Helping

You’re on vacation when suddenly….

Page 72: Why Defragmenting Your Indexes Isn't Helping

Performance is

bad and Ted says

it’s because you

don’t have an

index defrag job

Page 73: Why Defragmenting Your Indexes Isn't Helping

The devs won’t

look at any code

till we add that job

and run it, is that

OK?

Page 74: Why Defragmenting Your Indexes Isn't Helping

How to react

“The problem is high fragmentation.”

“So you guarantee that

rebuilding the indexes will fix it?”

“Uhhhh…”

“What metric shall we monitor to

know that the rebuild fixed it?”

“Ummmm…query runtime?”

“Great. Give me a query, and the current average

runtime, and what you expect it’ll be afterwards.”

Page 75: Why Defragmenting Your Indexes Isn't Helping

The two kinds of fragmentation

Why the fix makes things worse

The better performance fix

When people insist on rebuilds

What to do in overnight windows

This deck: BrentOzar.com/go/defrag

So what do I do daily?

Page 76: Why Defragmenting Your Indexes Isn't Helping

Lemme show you something awful.

Page 77: Why Defragmenting Your Indexes Isn't Helping

Step 1: create database, back it up.

CREATE DATABASE BrandNewCar;

GO

BACKUP DATABASE BrandNewCar TO

DISK='BrandNewCar.bak';

GO

BACKUP LOG BrandNewCar TO

DISK='BrandNewCar_Log1.trn';

Page 78: Why Defragmenting Your Indexes Isn't Helping

Step 2: put some data in it.

USE BrandNewCar;

GO

CREATE TABLE dbo.Options

(OptionName VARCHAR(50));

INSERT INTO dbo.Options

VALUES ('Leather seats'),

('Sunroof'),

('Racing stripes');

Page 79: Why Defragmenting Your Indexes Isn't Helping

Step 3: back up our valuable car.

BACKUP LOG BrandNewCar TO

DISK='BrandNewCar_Log2.trn';GO

Page 80: Why Defragmenting Your Indexes Isn't Helping

Step 4: look inside your car.

Shut down SQL Server (or set your database offline)

Open XVI32 – free hex editor

Open your database file

Do a control-F for Sunroof

Nice data you’ve got there.

Sure would be a shame if something happened to it.

Page 81: Why Defragmenting Your Indexes Isn't Helping

What causes corruption?

Shared storage failures and bugs

Page 82: Why Defragmenting Your Indexes Isn't Helping

What causes corruption?

Microsoft SQL Server bugs

Page 83: Why Defragmenting Your Indexes Isn't Helping

Step 5: let’s cause corruption.

Change Leather Seats to something else

Save the file and close XVI32

Start up your SQL Server (or bring database online)

Page 84: Why Defragmenting Your Indexes Isn't Helping

SQL Server looks the other way

SQL Server doesn’t detect the damage on startup because it doesn’t read every page from every

table.

Ways to discover the damage:

• SELECT * FROM dbo.BrandNewCar;

• DBCC CHECKDB();

• ALTER TABLE dbo.Options REBUILD;

Page 85: Why Defragmenting Your Indexes Isn't Helping

Now, how do you fix this?

If this was our real production server,

we’d be taking our application down,

and restoring from backup.

In real life: BrentOzar.com/go/corruption

Page 86: Why Defragmenting Your Indexes Isn't Helping

We get corruption sometime on Sunday

Full backup Sunday

12 am

(have this file)Data file corruption

at 10 am to one

clustered index

Log

backup

Log

backup

Log

backup

Log

backup

Successful

CHECKDB 10

pm

Page 87: Why Defragmenting Your Indexes Isn't Helping

Corruption is detected – but not acted on

Full backup Sunday

12 am

(have this file)Data file corruption

at 10 am to one

clustered index

Full backup Monday

12 am (have this file)

Log

backup

Log

backup

Log

backup

Log

backupLog

backup

Log

backup

Successful

CHECKDB 10

pmPage is read,

CHECKSUM doesn’t

match

Page 88: Why Defragmenting Your Indexes Isn't Helping

We only keep 24 hours of log backup files

Full backup Sunday

12 am

(have this file)

Full backup

Tuesday 12 am

(have this file)Data file corruption

at 10 am to one

clustered index

Full backup Monday

12 am (have this file)

Log

backup

Log

backup

Log

backup

Log

backupLog

backup

Log

backup

Log

backup

Log

backup

Deleted log backup files

Successful

CHECKDB 10

pmPage is read,

CHECKSUM doesn’t

match

Log

backup

Page 89: Why Defragmenting Your Indexes Isn't Helping

Will you lose data? How much?

Full backup Sunday

12 am

(have this file)

Full backup

Tuesday 12 am

(have this file)Data file corruption

at 10 am to one

clustered index

Full backup Monday

12 am (have this file)

Log

backup

Log

backup

Log

backup

Log

backupLog

backup

Log

backup

Log

backup

Log

backup

Deleted log backup files

Successful

CHECKDB 10

pmPage is read,

CHECKSUM doesn’t

match

Log

backup

User

finally

calls in

Page 90: Why Defragmenting Your Indexes Isn't Helping

What could you do to lose less data?

Full backup Sunday

12 am

(have this file)

Full backup

Tuesday 12 am

(have this file)Data file corruption

at 10 am to one

clustered index

Full backup Monday

12 am (have this file)

Log

backup

Log

backup

Log

backup

Log

backupLog

backup

Log

backup

Log

backup

Log

backup

Deleted log backup files

Successful

CHECKDB 10

pmPage is read,

CHECKSUM doesn’t

match

Log

backup

User

finally

calls in

Page 91: Why Defragmenting Your Indexes Isn't Helping

Ways to lose less data

Set up alerts for corruption errors: https://BrentOzar.com/go/alerts

Keep transaction log backup files longer

(dictated by your RPO, RTO, and CHECKDB frequency)

Run CHECKDB more often (and act fast on the outputs)

The more of these you do, the better your chances are to keep your job.

Page 92: Why Defragmenting Your Indexes Isn't Helping

DBAs don’t get fired

for slow performance.

Page 93: Why Defragmenting Your Indexes Isn't Helping

DBAs get fired

for losing data.

Page 94: Why Defragmenting Your Indexes Isn't Helping

Run CHECKDB as frequently as practical.

Forget shuffling indexes around every night.

It’s time to run CHECKDB in that time window instead.

Page 95: Why Defragmenting Your Indexes Isn't Helping

Recap

Yay, it’s over!

Page 96: Why Defragmenting Your Indexes Isn't Helping

What you learned

External fragmentation = pages out of order on disk(Only matters when you’re reading from disk)

Internal fragmentation = empty space on pages(Matters a lot, and fix this with judicious rebuilds)

Fill factor = internal fragmentation(Set this, and you’re making internal fragmentation worse)

Index maintenance is fine,

but it doesn’t solve most wait types.Find your top wait type with sp_BlitzFirst and focus on it.

Page 97: Why Defragmenting Your Indexes Isn't Helping

What you’ll do tomorrow

1. Set fill factor at the server level back to 100%.

2. Use sp_Blitz and sp_BlitzIndex to check for index fill factors <80%, and set those

back up to 80% or higher (or 100%).

3. Rebuild your indexes once to atone for those past sins,

getting them back up to 100% fill factor.

4. Monitor wait time per hour,

and use the scientific method to improve it.

This deck & demos: BrentOzar.com/go/defrag

Page 98: Why Defragmenting Your Indexes Isn't Helping

And stop reading advice

from the SQL Server 7.0 guys.


Recommended