24
Include or not include? That is the question! Oleksii Kovalov Cloudworks LLC [email protected]

Include or not include? A fairy tale about indexes

Embed Size (px)

Citation preview

Include or not include?

That is the question!

Oleksii Kovalov

Cloudworks LLC

[email protected]

Fairy taleIncluded columns?

Not so good!

Who told you that?

Our DBA!

He is wrong!

Main problem of all new features

1. Vendor invents New® Cool™ Feature

2. Nobody knows about “new cool feature”

3. Clever guy discovers feature and tells you about it

4. You use this feature

5. You shoot in foot using this new feature

6. ??????

7. PROFIT!!!

What is index?

On-disk structure used to improve data access

Cure or poison? It depends on how smart and lucky you are

Main rule: keep your index small enough

Types of indexes

Clustered indexes Non-clustered indexes

Usual nonclustered index Covering index Index with included columns

How it works?

Data level

Leaf level

Intermediate level(s)

Root level

Usual Covering Included

Index restrictions# of columns Row size MAX data types

Usual / covering index

16 key 900 bytes No

Index with included columns

16 key1023 non key

900 bytes key+ Not limited data

Yes

Sandbox

Single wide table

80 columns

25 millions of rows

793 bytes per row

~10 rows per data page

~18 gigabytes of data

Strike while the iron is hot!

select [Item No_] ,sum([Valued Quantity]) as

Qtyfrom dbo.ValueEntry where[Item No_] between

'1'and '1000' group by [Item No_]

Scan count 1 logical reads 2,415,258

physical reads 4 read-ahead 2,423,017 18 Gb of data read rows 3579 17 minutes

Usual index

create index SimpleIndex on [Value Entry]([Item No_])

Scan count 1 logical reads 24,843 physical reads 2 read-ahead 41,560 324 Mb read rows 3579 37 seconds

Covering index

Scan count 1 logical reads 19 physical reads 2 read-ahead reads 15 120 Kb read rows 3579 12 ms.

create index CoveringIndex on [ValueEntry]([Item No_],[Valued

Quantity])

Included columns

Scan count 1 logical reads 18 physical reads 1 read-ahead reads 15 120 Kb read rows 3579 11 ms.

create index IndexWithIncludedColumn on [ValueEntry]([Item No_])include([Valued Quantity])

So…. What the difference?Duration Logical Read-ahead Data read

No index 17 minutes 2,415,258 2,423,017 18.4 Gb

Usual 35 sec, x30 21,396 40,671 324 Mb

Covering 12 ms, x2916 19 15 120 Kb

Included 11 ms, x1.1 18 15 120 Kb

Size does matter?Size, Mb Depth Index row size Leaf pages Non-leaf pages

No index 18,000 1 800 2,407,400 7,884

Usual 456 3 17 58,203 160

Covering 870 4 34 110,821 541 (0.4%)

Included 868 3 34 110,820 302(0.27%)

Covering 3+2 1,679 4 66 213,068 1926 (0.9%)

Included 3+2 1,672 4 66 213,068 1009 (0.4%)

What about updates?

Search duration Duration Logical reads RA

No index 17 minutes 17 minutes 2,415,258 2,418,718

Usual 35 seconds 35 seconds 41,879 41,560

Covering 12 ms 36 seconds 52,836+7,256 40,890

Included 10 ms 35 seconds 45,467 40,664

update t set [Valued Quantity] = [Valued Quantity] + 1 from dbo.[ValueEntry] t where[Item No_] between '1' and '1000‘

Recommendations

Leave your existing indexes alone New index can have included columns Keep your index small Rewrite your query Redesign your data schema Consider using indexed views Consider using filtered index

Redesign, denormalizeselect [Item No_],sum([Valued Quantity])from ValueEntry where [Source No_] = 'ANONYMOUS'

and [Inventory Posting Group] = 'STANDARD' and [Source Posting Group] = 'STANDARD' and [Item No_] between '1' and '1000'

group by [Item No_]

create index Wide3 on dbo.ValueEntry([Item No_],[Source No_], [Inventory Posting Group],[Source Posting Group]) include([Valued Quantity])

alter table dbo.ValueEntry add Flag3 as cast(case when [Source No_] = 'ANONYMOUS' and [Inventory Posting Group] = 'STANDARD' and [Source Posting Group] =

'STANDARD' then 1 else 0 end as bit) persisted

create index Flag3 on dbo.ValueEntry([Item No_],[Flag3]) include([Valued Quantity])

select [Item No_],sum([Valued Quantity]) from ValueEntry Where Flag3 = 1 and [Item No_] between '1' and '1000' group by [Item No_]

Indexed views & filtered indexcreate view ValueEntryIndexedView with schemabinding as select[Item No_],sum([Valued Quantity]) as [Valued Quantity]             , sum([Invoiced quantity]) as [Invoiced quantity]             ,count_big(*) as Cnt from dbo.ValueEntry group by [Item No_] go create unique clustered index cl on ValueEntryIndexedView([Item No_]) go

create index FilteredIndex on [ValueEntry]([Item No_], [Valued Quantity]) where [Item No_] >= '1' and [Item No_] <= '1050‘

Indexed views etc statisticsDuration Logical Read-ahead Data read

No index 17 minutes 2,415,258 2,423,017 18.4 Gb

Usual 35 sec, x30 21,396 40,671 324 Mb

Covering 12 ms, x2916 19 15 120 Kb

Included 11 ms, x1.1 18 15 120 Kb

Indexed view 3 3 2 16Kb

Filtered index 3 17 15 120Kb

Wide index 3 30 26 208Kb

Flag index 3 19 15 120Kb

Indexed views etc - sizeSize, Mb Depth Index row size Leaf pages Non-leaf pages

No index 18,000 1 800 2,407,400 7,884

Usual 456 3 17 58,203 160

Covering 870 4 34 110,821 541 (0.4%)

Included 868 3 34 110,820 302(0.27%)

Covering 3+2 1,679 4 66 213,068 1926 (0.9%)

Included 3+2 1,672 4 66 213,068 1009 (0.4%)

Indexed view 10 3 58 1,249 4

Filtered index 21 3 34 2,614 14

Wide 1,549 4 61 196,977 1,241

Flag 892 4 35 113,898 369

Indexed view & filtered index - updates

Search duration Duration Logical reads RA

Scan 17 minutes 21 minutes 2,415,258 2,418,718

Usual 35 seconds 35 seconds 41,879 41,560

Covering 12 ms 36 seconds 52,836+7,256 40,890

Included 10 ms 35 seconds 45,467 40,664

Indexed view 3 ms 35 seconds 41978+14684 41560

Filtered index 3 ms 35 seconds 45163+7262 40721

update t set [Valued Quantity] = [Valued Quantity] + 1 from dbo.[ValueEntry] t where[Item No_] between '1' and '1000‘

So – what conclusion?

Included columns is not a silver bullet Helpful when transforming unique index to

covering Helps to avoid limit of 16 columns and 900 bytes –

if you really need it To save disk space – use filtered index or indexed

view

Thanks!http://technet.microsoft.com/en-us/library/ms177484%28v=sql.105%29.aspx

http://technet.microsoft.com/en-US/library/aa964133%28v=SQL.90%29.aspx

http://technet.microsoft.com/en-us/library/ms190457.aspx

http://technet.microsoft.com/en-us/library/ms190806.aspx

Sponsors