Upload
alexey-kovaliov
View
77
Download
1
Embed Size (px)
Citation preview
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
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