You are on page 1of 53

Introduction to

SQL Server Indexing

Greg Robidoux
President of Edgewood Solutions
Co-founder of MSSQLTips.com
gregr@edgewoodsolutions.com
About Speaker
• Greg Robidoux
• Founder of Edgewood Solutions
• Co-founder of MSSQLTips.com
• Working with SQL Server since 1999
• Authored over 200 tips on various websites

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 2


Agenda
• Purpose of indexing
• Types of Indexes
• Index Options
• Creating Indexes
• Index Usage
• Index Maintenance
• Q and A

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 3


Purpose of Indexing
• Pros
– Find things faster
– Less work to find
• Cons
– Requires setup
– Requires maintenance
– Requires more space

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 4


Purpose of SQL Server Indexing
• Find data faster
• Improves database and app performance
• Allows database and application to scale
• Reduces overhead - CPU, IO and Memory
• Happy Users (it might even get you a raise )

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 5


When to create indexes
• For SELECTs, UPDATEs and DELETEs
• Queries that are selective (not entire table)
• When column(s) are used for
– WHERE clause
– table JOINs
– Primary Keys
– Foreign Keys
– Unique Keys
– ORDER BY clause
– GROUP BY clause
• Balancing Act – don’t over index

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 6


Types of Indexes

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 7


Data Storage
• Actual table data can be stored two ways
– Cluster – base data is indexed
– Heap – base data is not indexed

Source: http://msdn.microsoft.com/en-us/library/ms130214.aspx

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 8


Clustered Index
• Determines how data is stored for the table
• A table can have one or none (heap)
• Data sorted and stored based on clustered index
• Can be 1 or more columns
• Keep narrow (small data types and columns)
– Non-clustered indexes contain clustered columns
• Does not have to be the primary key
– By default SSMS makes it a clustered index

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 9


Non-clustered Index
• Fast access to certain columns in the table
• Can have up to 999 per table
• Can be 1 or more columns
• Data types – int, varchar, date, etc.
• Contains clustered columns or RID (row identifier) of
heap
• Non-clustered indexes lookup columns that are not part
of non-clustered index
• Too many indexes is not necessarily a good thing

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 10


Index Structures
Clustered Index Non-clustered Index

Source: http://msdn.microsoft.com/en-us/library/ms130214.aspx

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 11


Non-clustered Index Storage
Clustered as unique
caseID non-clustered
ID clustered

Clustered as not unique

Clustered with multiple columns as not unique

Above examples use DBCC PAGE and DBCC IND to get data – tip 1578 - http://www.mssqltips.com/searchbytipid.asp

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 12


Non-clustered Index Storage
HEAP
caseID non-clustered

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 13


Other Indexes
• XML
– Indexes XML data types for fast data retrieval from XML
documents stored in a database
• Spatial
– Indexes spatial data used for mapping points such as
geometry and geography – tip 1976
• Non-Clustered Columnstore
– Indexes data at a column level instead of at a row level –
read only – tip 2586
• Full Text
– Indexes words and phrases like a search engine – tip 1332

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 14


Index Options

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 15


Primary Key Constraint
• Unique identifier for a row in a table
• One per table
• One or more columns that are unique
• Either clustered or non-clustered
• Can create using table designer in SSMS, by default it
makes it a clustered index
• Can create using T-SQL

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 16


Foreign Key Constraint
• Column(s) that maintain relationship to data in
other tables
• Linked based on primary key in the other table
• This is not another index it is a constraint
• Can create using SSMS or T-SQL

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 17


Unique
• Enforces uniqueness of the index
• Clustered
– If not created as UNIQUE, a 4-byte uniqueifier
column is added for internal use
• Use columns defined as NOT NULL

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 18


Covering Index
• Only for non-clustered indexes
• Can be one or more columns that satisfies
a result set
• SELECT performance gains

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 19


Included Columns
• Only for non-clustered indexes
• Add additional columns with index to improve
SELECT performance
• Included columns are not part of the key
• Can include these data types
– Varchar(max), Nvarchar(max), varbinary(max), xml, etc.
– No support for text, ntext and image data types
• Additional storage needed to store included
columns
Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 20
Sorting
• Can create indexes in ascending or
descending order
• Ascending is the default
• Can sort data ASC for one column and
DESC on a different column
– TipID = 1337

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 21


Filtered Index
• Index includes WHERE
CREATE NONCLUSTERED
INDEX NCLIX_ID
ON dbo.Child(ID)
WHERE ID < 5

• Non-clustered indexes
• Better performance
• Less storage
• Additional information
– TipID = 1785

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 22


Creating Indexes

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 23


Indexes for New Table

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 24


Indexes for New Table

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 25


Create Index Using SSMS
• Tip 3096

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 26


Create Clustered Index

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 27


Create Non-clustered index

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 28


Clustered and Non-clustered Index Options

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 29


Index Storage

Clustered Index Non-Clustered Index

Tips 1200, 2601

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 30


Filter Index

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 31


T-SQL Create Clustered Index
CREATE CLUSTERED INDEX (indexName)
ON (tableName) ( columns ASC | DESC )

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 32


T-SQL Create Non-Clustered Index
CREATE NONCLUSTERED INDEX (indexName)
ON (tableName) ( columns ASC | DESC )

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 33


Examples
SELECT id FROM dbo.Child WHERE id = 2
– Clustered or non-clustered on id

SELECT id, enterDate FROM dbo.Child WHERE id = 2


– Clustered on id
– or non-clustered on id with included column enterDate

SELECT p.lname, a.city


FROM dbo.person p
INNER JOIN dbo.address a ON p.addressID = a.addressID
WHERE p.lname = ‘Jones’
– Clustered or non-clustered on person.lname
– Clustered or non-clustered on address.addressID

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 34


Examples
SELECT * FROM dbo.Child WHERE id = 2
– Clustered on id

SELECT p.fname, p.lname, a.city


FROM dbo.person p
INNER JOIN dbo.address a ON p.addressID = a.addressID
WHERE p.lname = ‘Jones’ and a.city = ‘Boston’
– Clustered on person.lname
– Non-clustered on address.addressID with included column address.city

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 35


Index Usage

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 36


Operational Stats
• Shows how indexes are maintained – tip 1239
SELECT OBJECT_NAME(A.[OBJECT_ID]) AS [OBJECT NAME],
I.[NAME] AS [INDEX NAME],
A.LEAF_INSERT_COUNT,
A.LEAF_UPDATE_COUNT,
A.LEAF_DELETE_COUNT
FROM SYS.DM_DB_INDEX_OPERATIONAL_STATS (NULL,NULL,NULL,NULL ) A
INNER JOIN SYS.INDEXES AS I ON I.[OBJECT_ID] = A.[OBJECT_ID] AND I.INDEX_ID = A.INDEX_ID
WHERE OBJECTPROPERTY(A.[OBJECT_ID],'IsUserTable') = 1

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 37


Usage Stats
• Shows how indexes are used – tip 1239
SELECT OBJECT_NAME(S.[OBJECT_ID]) AS [OBJECT NAME],
I.[NAME] AS [INDEX NAME],
USER_SEEKS,
USER_SCANS,
USER_LOOKUPS,
USER_UPDATES
FROM SYS.DM_DB_INDEX_USAGE_STATS AS S
INNER JOIN SYS.INDEXES AS I ON I.[OBJECT_ID] = S.[OBJECT_ID] AND I.INDEX_ID = S.INDEX_ID
WHERE OBJECTPROPERTY(S.[OBJECT_ID],'IsUserTable') = 1

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 38


Unused Indexes
• Additional overhead to maintain
• Additional unneeded storage for index
• Identify and remove unused indexes
• Look for duplicates that are not being used
• Tip 1545

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 39


Missing Indexes
• SQL Server identifies and stores
information about potential new indexes
• Also when looking at query plan, SQL will
recommend new indexes

• Tip 1634

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 40


Finding a Better Clustered Index
• Review index usage stats
• If one index has high seeks and there are
similar counts for lookups you could swap
indexes

• Tip 1642

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 41


Execution Plans
• Use execution plans to see if indexes are
being used

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 42


Execution Plans
Query 1
• clustered on ID

Query 2
• no clustered
• Non-cluster on CaseID

Query 3
• clustered on ID
• Non-cluster on CaseID

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 43


Index Maintenance

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 44


Index Space
• Get Space Used Per Index
SELECT
o.name AS TableName, i.name AS IndexName, i.index_id AS IndexID,
SUM(page_count * 8)/1024 AS IndexSizeMB
FROM sys.dm_db_index_physical_stats(db_id(), NULL, NULL, NULL, 'DETAILED') AS s
JOIN sys.indexes AS i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
JOIN sys.objects AS o ON s.[object_id] = o.[object_id]
GROUP BY o.name, i.name, i.index_id
ORDER BY o.name, i.name

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 45


Changing an Index
• You can use SSMS to make changes
• You can use T-SQL command
ALTER INDEX
• Some changes will require index to be
rebuilt
• Adding or dropping clustered index
requires pointers in non-clustered indexes
to be updated
Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 46
Deleting an Index
• You can use SSMS to
delete an index
• You can use T-SQL
command
DROP INDEX

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 47


Fragmentation
• Fragmentation is caused when you
INSERT, DELETE or UPDATE data
• Adding new records causes page splits
• The more changes that occur the messier
the index becomes (fragmented)
• Can be fixed by either Rebuilding or
Reorganizing an index
• Tip 1708
Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 48
Checking Fragmentation
SELECT object_name(IPS.object_id) AS [TableName],
SI.name AS [IndexName],
SI.index_id,
IPS.index_level,
IPS.avg_fragmentation_in_percent,
IPS.page_count,
IPS.record_count,
IPS.fragment_count
FROM sys.dm_db_index_physical_stats(db_id(N'Test'), NULL, NULL, NULL , 'DETAILED') IPS
JOIN sys.tables ST WITH (nolock) ON IPS.object_id = ST.object_id
JOIN sys.indexes SI WITH (nolock) ON IPS.object_id = SI.object_id AND IPS.index_id = SI.index_id
WHERE ST.is_ms_shipped = 0
ORDER BY 1,3,4

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 49


Index Maintenance Best Practices
• Fragmentation Levels
– Less than 10% - No action
– Between 10% and 29% - Reorganize
– Greater than 30 % - Rebuild
• Don’t rebuild all indexes, be selective
• Understand impact
• Retain a log for the index maintenance

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 50


Index Maintenance Commands
• REBUILD INDEX
– ALTER INDEX ALL ON dbo.Authors REBUILD WITH (FILLFACTOR = 80,
SORT_IN_TEMPDB = ON);
– ALTER INDEX [IX_Test] ON [dbo].[Test] REBUILD WITH (ONLINE = ON);
– ALTER INDEX ALL ON [dbo].[Test] REBUILD WITH (ONLINE = ON);

• REORGANIZE INDEX
– ALTER INDEX au_id_ind ON dbo.Authors REORGANIZE;

• Additional Information
– TipID = 1018, 1791, 2361

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 51


Maintenance Plans

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 52


Thank You and Next Steps!
• Review index usage statistics
• Put proper index maintenance in place
• Review query plans for possible new indexes
• Remove indexes that are not being used
• Review the tips outline in presentation

• Upcoming events
http://www.mssqltips.com/sql-server-event-list/

• Visit www.idera.com to get SQL Server tools

Copyright (c) 2006-2013 Edgewood Solutions, LLC All rights reserved 53

You might also like