SlideShare a Scribd company logo
1 of 34
MSSQL Server Indexes 
Ram Kedem
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Internal fragmentation 
•When records are stored non-contiguously inside the page, then it is called internal fragmentation. 
•In other words, internal fragmentation is said to occur if there is unused space between records in a page. 
•This fragmentation occurs through the process of data modifications (INSERT, UPDATE, and DELETE statements) that are made against the table and therefore, to the indexes defined on the table. 
•As these modifications are not equally distributed among the rows of the table and indexes, the fullness of each page can vary over time. 
•This unused space causes poor cache utilization and more I/O, which ultimately leads to poor query performance.
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
External Fragmentation 
•When on disk, the physical storage of pages and extents is not contiguous. 
•When the extents of a table are not physically stored contiguously on disk, switching from one extent to another causes higher disk rotations.
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Identify Fragmentation – Demo 1 
-- 1. Identify the object using sys.indexes and sys.objects 
USE Northwind; 
GO 
SELECT * FROM sys.objects WHERE name = 'Products' 
SELECT * FROM sys.indexes 
WHERE object_id = object_id('products')
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Identify Fragmentation – Demo 1 
-- 2. Query the index physical stats DMV using sys.dm_db_index_physical_stats 
-- The procedure gets the following parameters 
-- 1. Database ID 
-- 2. Object ID (the table) 
-- 3. Index ID 
-- 4. Partition ID (if needed) 
-- 5. Scope of detail (LIMITED , SAMPLED , DETAILED) 
SELECT index_id,index_type_desc, 
index_level, 
avg_fragmentation_in_percent AS 'external fragmentation', 
avg_page_space_used_in_percent AS 'internal fragmentation', 
page_count 
FROM sys.dm_db_index_physical_stats(DB_ID(),533576939,NULL,NULL,'DETAILED');
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Identify Fragmentation – Demo 1 
-- or 
DECLARE @object_id int 
SELECT @object_id = object_id FROM sys.objects WHERE name = 'Products' 
SELECT index_id,index_type_desc, 
index_level, 
avg_fragmentation_in_percent AS 'external fragmentation', 
avg_page_space_used_in_percent AS 'internal fragmentation', 
page_count 
FROM sys.dm_db_index_physical_stats(DB_ID(),@object_id,NULL,NULL,'DETAILED');
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Identify Fragmentation – Demo 1 
SELECT name 
FROM sys.indexes 
WHERE object_id = object_id('products') 
AND index_id = 2 
ALTER INDEX CategoriesProducts ON products REBUILD
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
External / Internal Fragmentation 
•External Fragmentation - Aim lower than 10% 
•avg_fragmentation_in_percent: This is a percentage value that represents external fragmentation. 
•The lower this value, the better it is. If this value is higher than 10%, some corrective action should be taken. 
•Internal Fragmentation - Aim higher than 75% 
•avg_page_space_used_in_percent: This is an average percentage use of pages that represents to internal fragmentation. 
•Higher the value, the better it is. If this value is lower than 75%, some corrective action should be taken. 
•If an index is below a certain size, defragmentation doesn't end up doing anything. 
•In some cases the index is tiny, so fragmentation doesn't matter and won't get defragmented anyway.
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Numeric Index Data 
•Numeric 
•Indexes with numeric keys work efficiently 
•Integer types are the most efficient (Exact numeric types) 
•Approximate data types (float and real) much less efficient 
CREATE TABLE test_tbl 
(numeric_col int) 
CREATE INDEX numeric_col_ix ON test_tbl(numeric_col) 
DROP INDEX test_tbl.numeric_col_ix 
DROP TABLE test_tbl
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Date Index Data 
•Date-Related Index Data 
•Date data types are generally good candidates for index keys 
•Only slightly less efficient than integer data 
•date (Accuracy of 1 day) more efficient than datetime (Accuracy of 3.33 milliseconds) 
CREATE TABLE test_tbl 
(date_col date) 
CREATE INDEX date_co_ix ON test_tbl(date_col) 
DROP INDEX test_tbl.date_co_ix 
DROP TABLE test_tbl
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Character Index Data 
•Character data types are much less efficient when used in index keys 
•Character values tend to be much larger than numeric values 
CREATE TABLE test_tbl 
(char_col int) 
CREATE INDEX char_col_ix ON test_tbl(char_col) 
DROP INDEX test_tbl.char_col_ix 
DROP TABLE test_tbl
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
GUID Index Data 
CREATE TABLE test_tbl 
(product_id UNIQUEIDENTIFIER , 
product_name varchar(25)) 
CREATE INDEX product_id_ix ON test_tbl(product_id) 
DROP INDEX test_tbl.product_id_ix 
DROP TABLE test_tbl
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Computed Column and Indexes 
DROP TABLE computed_tbl ; 
GO 
CREATE TABLE computed_tbl 
(id int, 
-- date_col AS RAND() PERSISTED 
-- Since it's not a deterministic function it cannot be PERSISTED 
rand_col AS RAND(), 
id_col AS (id+1) PERSISTED , 
decimal_col DECIMAL(3, 1)); 
GO 
INSERT INTO computed_tbl (id, decimal_col) 
VALUES (1 , 2.1),(2, 3.4),(NULL, 4.7) 
-- Values computed every select 
SELECT * FROM computed_tbl 
-- The expressions must be deterministic 
---------------------------------------- 
CREATE INDEX test_ix ON computed_tbl(rand_col) 
-- Works 
CREATE INDEX test_ix ON computed_tbl(id_col)
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Single Column vs. Composite Indexes 
-- Single Column 
----------------- 
DROP TABLE test_tbl 
SELECT productID , CategoryID , UnitPrice 
INTO test_tbl 
FROM northwind.dbo.products 
INSERT INTO test_tbl SELECT CategoryID , UnitPrice FROM test_tbl 
SELECT COUNT(*) FROM test_tbl 
SELECT * FROM test_tbl 
CREATE INDEX prod_id_ix ON test_tbl (productID) 
CREATE INDEX prod_cat_ix ON test_tbl (CategoryID) 
SELECT CategoryID FROM test_tbl ORDER BY CategoryID 
SELECT CategoryID FROM test_tbl ORDER BY CategoryID , productID
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Single Column vs. Composite Indexes 
-- Composite Indexes 
-------------------- 
DROP TABLE test_tbl 
SELECT productID , CategoryID , UnitPrice 
INTO test_tbl 
FROM northwind.dbo.products 
DECLARE @counter INT 
SET @counter = 1 
WHILE (@counter <=12) 
BEGIN 
INSERT INTO test_tbl SELECT CategoryID , UnitPrice FROM test_tbl 
SET @counter = @counter + 1 
END 
SELECT COUNT(*) FROM test_tbl 
CREATE INDEX prod_id_ix ON test_tbl (CategoryID, productID) 
SELECT CategoryID, productID FROM test_tbl ORDER BY CategoryID , productID 
SELECT CategoryID, productID FROM test_tbl ORDER BY productID , CategoryID
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Ascending vs. Descending Indexes 
DROP INDEX test_tbl.prod_id_ix 
CREATE INDEX prod_id_ix ON test_tbl(productID DESC) 
SELECT productID FROM test_tbl ORDER BY productID 
SELECT productID FROM test_tbl ORDER BY productID DESC 
DROP INDEX test_tbl.prod_id_ix 
CREATE INDEX prod_id_ix ON test_tbl (CategoryID DESC, productID) 
SELECT CategoryID FROM test_tbl ORDER BY CategoryID DESC, productID 
SELECT CategoryID FROM test_tbl ORDER BY CategoryID , productID
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Forwarding Points 
USE tempdb; 
GO 
DROP TABLE dbo.PhoneLog 
-- Step 1: Create a table as a heap 
CREATE TABLE dbo.PhoneLog 
( PhoneLogID int IDENTITY(1,1) NOT NULL, 
LogRecorded datetime2 NOT NULL, 
PhoneNumberCalled nvarchar(100) NOT NULL, 
CallDurationMs int NOT NULL 
); 
GO 
-- Step 2: Query sys.indexes to view the structure 
SELECT index_id, 
index_type_desc, 
forwarded_record_count, 
page_count 
FROM sys.dm_db_index_physical_stats(DB_ID(),object_id('dbo.PhoneLog'),NULL,NULL,'SAMPLED');
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Forwarding Points 
-- Step 3: Query sys.indexes to view the structure 
SELECT index_id, 
index_type_desc, 
forwarded_record_count, 
page_count 
FROM sys.dm_db_index_physical_stats(DB_ID(),object_id('dbo.PhoneLog'), NULL,NULL,'SAMPLED'); 
-- Step 4: Insert some data into the table 
SET NOCOUNT ON; 
DECLARE @Counter int = 0; 
WHILE @Counter < 1000 BEGIN 
INSERT dbo.PhoneLog (LogRecorded, PhoneNumberCalled, CallDurationMs) 
VALUES(SYSDATETIME(),'999-9999',CAST(RAND() * 1000 AS int)); 
SET @Counter += 1; 
END; 
GO
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Forwarding Points 
SELECT * FROM dbo.PhoneLog 
SELECT index_id, 
index_type_desc, 
forwarded_record_count, 
page_count 
FROM sys.dm_db_index_physical_stats(DB_ID(),object_id('dbo.PhoneLog'),NULL,NULL,'SAMPLED');
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Forwarding Points 
-- Step 5: Modify the data in the table using replicate 
SET NOCOUNT ON; 
DECLARE @Counter int = 0; 
WHILE @Counter < 1000 BEGIN 
UPDATE dbo.PhoneLog SET PhoneNumberCalled = REPLICATE('9',CAST(RAND() * 100 AS int)) 
WHERE PhoneLogID = @Counter; 
IF @Counter % 100 = 0 PRINT @Counter; 
SET @Counter += 1; 
END; 
GO 
-- Step 6: Check the level of fragmentation via sys.dm_db_index_physical_stats 
SELECT * FROM dbo.PhoneLog 
SELECT index_id, 
index_type_desc, 
forwarded_record_count, 
page_count 
FROM sys.dm_db_index_physical_stats(DB_ID(),object_id('dbo.PhoneLog'),NULL,NULL,'SAMPLED'); 
-- Step 8: Rebuild the table 
ALTER TABLE dbo.PhoneLog REBUILD; 
GO
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Create Clustered Indexes 
-- 1. Can be created by specifying PRIMARY KEY on table, when creating it 
CREATE TABLE dbo.Article 
( ArticleID int IDENTITY(1,1) PRIMARY KEY, 
ArticleName nvarchar(50) NOT NULL, 
PublicationDate date NOT NULL 
); 
-- 2. Can be created by specifying PRIMARY KEY on table, when altering it 
CREATE TABLE dbo.LogData 
( LogID int IDENTITY(1,1), 
LogData xml NOT NULL 
); 
ALTER TABLE dbo.LogData 
ADD CONSTRAINT PK_LogData 
PRIMARY KEY (LogId);
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Create Clustered Indexes 
-- 3. You can add the term NONCLUSTERED to the definition of the PRIMARY KEY 
-- to avoid this behavior if you wish 
CREATE TABLE emps1 
(empid int PRIMARY KEY NONCLUSTERED , 
empName varchar(30)) 
-- 3. Can be created directly 
CREATE TABLE emps2 
(empid int, 
empName varchar(30)) 
CREATE CLUSTERED INDEX CL_empid 
ON dbo.emps2(empName); 
-- View the different table types 
SELECT tab.object_id , tab.name AS 'TableName' , i.type_desc , i.name AS 'IndexName' 
FROM sys.indexes i, sys.tables tab 
WHERE i.object_id = tab.object_id
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Drop Clustered Indexes 
DROP INDEX CL_empid ON dbo.emps2; 
ALTER TABLE dbo.Article 
DROP CONSTRAINT PK__Article__9C6270C8C831D6B7;
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Altering a Clustered Index 
•Index Rebuild : This process drops the existing Index and Recreates the index. 
•Index Reorganize : This process physically reorganizes the leaf nodes of the index. 
•Recommendation: 
•Index should be rebuild when index fragmentation is great than 40%. 
•Index should be reorganized when index fragmentation is between 10% to 40%. 
•Index rebuilding process uses more CPU and it locks the database resources. 
•SQL Server development version and Enterprise version has option ONLINE, which can be turned on when Index is rebuilt. ONLINE option will keep index available during the rebuilding.
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Altering a Clustered Index 
-- Rebuild 
ALTER INDEX PK_LogData ON dbo.LogData 
REBUILD; 
-- Disable 
ALTER INDEX PK_LogData ON dbo.LogData 
DISABLE; 
SELECT name , is_disabled FROM sys.indexes 
WHERE name = 'PK_LogData' 
-- Reorginize / Rebuild 
ALTER INDEX PK_LogData ON dbo.LogData 
REORGANIZE; 
ALTER INDEX PK_LogData ON dbo.LogData 
REBUILD;
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Fill Factor 
DROP TABLE emps3 
GO 
CREATE TABLE emps3 
(empid int CONSTRAINT emp3_id_pk PRIMARY KEY WITH (FILLFACTOR = 70), 
empname varchar(25)) 
ALTER INDEX emp3_id_pk ON emps3 
REBUILD WITH (FILLFACTOR = 80) 
GO
Heap Table Vs. Clustered Index In Depth
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Heap Table 
DROP TABLE dummyTable1 
CREATE TABLE DummyTable1 
(EmpId Int, 
EmpName Varchar(8000)) 
Insert Into DummyTable1 Values (4, Replicate ('d',2000)) 
Insert Into DummyTable1 Values (6, Replicate ('f',2000)) 
Insert Into DummyTable1 Values (1, Replicate ('a',2000)) 
Insert Into DummyTable1 Values (3, Replicate ('c',2000)) 
Insert Into DummyTable1 Values (10, Replicate ('j',2000)) 
Insert Into DummyTable1 Values (2, Replicate ('b',2000)) 
Insert Into DummyTable1 Values (5, Replicate ('e',2000)) 
Insert Into DummyTable1 Values (8, Replicate ('h',2000)) 
Insert Into DummyTable1 Values (9, Replicate ('i',2000)) 
Insert Into DummyTable1 Values (7, Replicate ('g',2000)) 
Select EmpID From DummyTable1 
GO 
-- Allow DBCC return info back to your session 
DBCC TRACEON(3604) 
GO
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Heap Table 
-- 2. View page allocations 
Declare @DBID Int, @TableID Int 
Select @DBID = db_id(), @TableID = object_id('DummyTable1') 
DBCC ind(@DBID, @TableID, -1) 
GO 
--PagePID is the physical page numbers used to store the table. In this case, three pages are 
--currently used to store the data. 
--IndexID is the type of index,Where: 
-- 0 – Datapage 
-- 1 – Clustered Index 
-- 2 – Greater and equal to 2 is an Index page (Non-Clustered Index and ordinary index), 
-- PageType tells you what kind of data is stored in each database, Where: 
-- 10 – IAM (Index Allocation MAP) 
-- 1 – Datapage 
-- 2 – Index page 
-- View each page contents 
Declare @DBID Int 
Select @DBID = db_id() 
DBCC page(@DBID, 1, 304, 3) 
GO
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Nonclustred index 
CREATE UNIQUE NONCLUSTERED INDEX DummyTable1_empid 
ON DummyTable1 (empid) 
GO 
Declare @DBID Int, @TableID Int 
Select @DBID = db_id(), @TableID = object_id('DummyTable1') 
DBCC ind(@DBID, @TableID, -1) 
GO 
-- View index page contents 
Declare @DBID Int 
Select @DBID = db_id() 
DBCC page(@DBID, 1, 312, 3) 
GO
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Clustered index 
DROP TABLE dummyTable2 
CREATE TABLE DummyTable2 
(EmpId Int Primary Key, 
EmpName Varchar(8000)) 
Insert Into DummyTable2 Values (4, Replicate ('d',2000)) 
Insert Into DummyTable2 Values (6, Replicate ('f',2000)) 
Insert Into DummyTable2 Values (1, Replicate ('a',2000)) 
Insert Into DummyTable2 Values (3, Replicate ('c',2000)) 
Insert Into DummyTable2 Values (10, Replicate ('j',2000)) 
Insert Into DummyTable2 Values (2, Replicate ('b',2000)) 
Insert Into DummyTable2 Values (5, Replicate ('e',2000)) 
Insert Into DummyTable2 Values (8, Replicate ('h',2000)) 
Insert Into DummyTable2 Values (9, Replicate ('i',2000)) 
Insert Into DummyTable2 Values (7, Replicate ('g',2000)) 
Select EmpID From DummyTable2 
GO
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Clustered index 
Declare @DBID Int, @TableID Int 
Select @DBID = db_id(), @TableID = object_id('DummyTable2') 
DBCC ind(@DBID, @TableID, -1) 
GO 
-- Possible to use this undocumented command to see page contents 
Declare @DBID Int 
Select @DBID = db_id() 
DBCC page(@DBID, 1, 317, 3) 
GO 
Declare @DBID Int, @TableID Int 
Select @DBID = db_id(), @TableID = object_id('DummyTable1') 
DBCC ind(@DBID, @TableID, -1) 
GO 
Declare @DBID Int 
Select @DBID = db_id() 
DBCC page(@DBID, 1, 286, 3) 
GO
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Clustered index (with secondary index) 
DROP TABLE dummyTable2 
CREATE TABLE DummyTable2 
(EmpId Int Primary Key, 
EmpName Varchar(8000), 
emp_lName varchar(10)) 
Insert Into DummyTable2 Values (4, Replicate ('d',2000), Replicate ('d',3)) 
Insert Into DummyTable2 Values (6, Replicate ('f',2000), Replicate ('f',3)) 
Insert Into DummyTable2 Values (1, Replicate ('a',2000), Replicate ('a',3)) 
Insert Into DummyTable2 Values (3, Replicate ('c',2000), Replicate ('c',3)) 
Insert Into DummyTable2 Values (10, Replicate ('j',2000), Replicate ('j',3)) 
Insert Into DummyTable2 Values (2, Replicate ('b',2000), Replicate ('b',3)) 
Insert Into DummyTable2 Values (5, Replicate ('e',2000), Replicate ('e',3)) 
Insert Into DummyTable2 Values (8, Replicate ('h',2000), Replicate ('h',3)) 
Insert Into DummyTable2 Values (9, Replicate ('i',2000), Replicate ('i',3)) 
Insert Into DummyTable2 Values (7, Replicate ('g',2000), Replicate ('g',3)) 
CREATE UNIQUE NONCLUSTERED INDEX DummyTable2_lname 
ON DummyTable2 (emp_lName) 
GO
Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent 
Clustered index (with secondary index) 
Select EmpID From DummyTable2 
GO 
Declare @DBID Int, @TableID Int 
Select @DBID = db_id(), @TableID = object_id('DummyTable2') 
DBCC ind(@DBID, @TableID, -1) 
GO 
-- Possible to use this undocumented command to see page contents 
Declare @DBID Int 
Select @DBID = db_id() 
DBCC page(@DBID, 1, 292, 3) 
GO 
UPDATE DummyTable2 SET EmpId = 100 WHERE EmpId = 1

More Related Content

What's hot

Chetan postgresql partitioning
Chetan postgresql partitioningChetan postgresql partitioning
Chetan postgresql partitioning
suniltomar04
 

What's hot (20)

Less08 Schema
Less08 SchemaLess08 Schema
Less08 Schema
 
SQL Tutorial - Basic Commands
SQL Tutorial - Basic CommandsSQL Tutorial - Basic Commands
SQL Tutorial - Basic Commands
 
DDL(Data defination Language ) Using Oracle
DDL(Data defination Language ) Using OracleDDL(Data defination Language ) Using Oracle
DDL(Data defination Language ) Using Oracle
 
Extensible Data Modeling
Extensible Data ModelingExtensible Data Modeling
Extensible Data Modeling
 
Ms sql-server
Ms sql-serverMs sql-server
Ms sql-server
 
View & index in SQL
View & index in SQLView & index in SQL
View & index in SQL
 
Introduction to mysql part 1
Introduction to mysql part 1Introduction to mysql part 1
Introduction to mysql part 1
 
Chapter 1 introduction to sql server
Chapter 1 introduction to sql serverChapter 1 introduction to sql server
Chapter 1 introduction to sql server
 
SQL Differences SQL Interview Questions
SQL Differences  SQL Interview QuestionsSQL Differences  SQL Interview Questions
SQL Differences SQL Interview Questions
 
Schemadoc
SchemadocSchemadoc
Schemadoc
 
Sql views
Sql viewsSql views
Sql views
 
Chetan postgresql partitioning
Chetan postgresql partitioningChetan postgresql partitioning
Chetan postgresql partitioning
 
Dbms lab Manual
Dbms lab ManualDbms lab Manual
Dbms lab Manual
 
Introduction to database
Introduction to databaseIntroduction to database
Introduction to database
 
Lab2 ddl commands
Lab2 ddl commandsLab2 ddl commands
Lab2 ddl commands
 
Starting with JSON Path Expressions in Oracle 12.1.0.2
Starting with JSON Path Expressions in Oracle 12.1.0.2Starting with JSON Path Expressions in Oracle 12.1.0.2
Starting with JSON Path Expressions in Oracle 12.1.0.2
 
Database Systems - SQL - DDL Statements (Chapter 3/3)
Database Systems - SQL - DDL Statements (Chapter 3/3)Database Systems - SQL - DDL Statements (Chapter 3/3)
Database Systems - SQL - DDL Statements (Chapter 3/3)
 
SQL for interview
SQL for interviewSQL for interview
SQL for interview
 
Custom Star Creation for Ellucain's Enterprise Data Warehouse
Custom Star Creation for Ellucain's Enterprise Data WarehouseCustom Star Creation for Ellucain's Enterprise Data Warehouse
Custom Star Creation for Ellucain's Enterprise Data Warehouse
 
Oracle: Basic SQL
Oracle: Basic SQLOracle: Basic SQL
Oracle: Basic SQL
 

Viewers also liked

Indexing the MySQL Index: Key to performance tuning
Indexing the MySQL Index: Key to performance tuningIndexing the MySQL Index: Key to performance tuning
Indexing the MySQL Index: Key to performance tuning
OSSCube
 
Column store indexes and batch processing mode (nx power lite)
Column store indexes and batch processing mode (nx power lite)Column store indexes and batch processing mode (nx power lite)
Column store indexes and batch processing mode (nx power lite)
Chris Adkin
 
MySQL Indexing - Best practices for MySQL 5.6
MySQL Indexing - Best practices for MySQL 5.6MySQL Indexing - Best practices for MySQL 5.6
MySQL Indexing - Best practices for MySQL 5.6
MYXPLAIN
 

Viewers also liked (20)

1 data types
1 data types1 data types
1 data types
 
Database indexing framework
Database indexing frameworkDatabase indexing framework
Database indexing framework
 
TSQL in SQL Server 2012
TSQL in SQL Server 2012TSQL in SQL Server 2012
TSQL in SQL Server 2012
 
Indexing the MySQL Index: Key to performance tuning
Indexing the MySQL Index: Key to performance tuningIndexing the MySQL Index: Key to performance tuning
Indexing the MySQL Index: Key to performance tuning
 
Indian movies games
Indian movies gamesIndian movies games
Indian movies games
 
Sql rally 2013 columnstore indexes
Sql rally 2013   columnstore indexesSql rally 2013   columnstore indexes
Sql rally 2013 columnstore indexes
 
Column store indexes and batch processing mode (nx power lite)
Column store indexes and batch processing mode (nx power lite)Column store indexes and batch processing mode (nx power lite)
Column store indexes and batch processing mode (nx power lite)
 
Database indexing techniques
Database indexing techniquesDatabase indexing techniques
Database indexing techniques
 
MS SQL Server
MS SQL ServerMS SQL Server
MS SQL Server
 
활용예시를 통한 Sql server 2012의 향상된 프로그래밍 기능 엿보기
활용예시를 통한 Sql server 2012의 향상된 프로그래밍 기능 엿보기활용예시를 통한 Sql server 2012의 향상된 프로그래밍 기능 엿보기
활용예시를 통한 Sql server 2012의 향상된 프로그래밍 기능 엿보기
 
2011년 KTH H3 컨퍼런스 Track B, 세션4 "Advanced Git" by A.J
2011년 KTH H3 컨퍼런스 Track B, 세션4 "Advanced Git" by A.J2011년 KTH H3 컨퍼런스 Track B, 세션4 "Advanced Git" by A.J
2011년 KTH H3 컨퍼런스 Track B, 세션4 "Advanced Git" by A.J
 
Introduction to TFS 2013
Introduction to TFS 2013Introduction to TFS 2013
Introduction to TFS 2013
 
MySQL: Indexing for Better Performance
MySQL: Indexing for Better PerformanceMySQL: Indexing for Better Performance
MySQL: Indexing for Better Performance
 
MySQL Indexing - Best practices for MySQL 5.6
MySQL Indexing - Best practices for MySQL 5.6MySQL Indexing - Best practices for MySQL 5.6
MySQL Indexing - Best practices for MySQL 5.6
 
Columnstore indexes in sql server 2014
Columnstore indexes in sql server 2014Columnstore indexes in sql server 2014
Columnstore indexes in sql server 2014
 
Intro to column stores
Intro to column storesIntro to column stores
Intro to column stores
 
SQL 2016 Mejoras en InMemory OLTP y Column Store Index
SQL 2016 Mejoras en InMemory OLTP y Column Store IndexSQL 2016 Mejoras en InMemory OLTP y Column Store Index
SQL 2016 Mejoras en InMemory OLTP y Column Store Index
 
SQL Server 2016 novelties
SQL Server 2016 noveltiesSQL Server 2016 novelties
SQL Server 2016 novelties
 
How to Design Indexes, Really
How to Design Indexes, ReallyHow to Design Indexes, Really
How to Design Indexes, Really
 
The Top Skills That Can Get You Hired in 2017
The Top Skills That Can Get You Hired in 2017The Top Skills That Can Get You Hired in 2017
The Top Skills That Can Get You Hired in 2017
 

Similar to 3 indexes

Business Intelligence Portfolio
Business Intelligence PortfolioBusiness Intelligence Portfolio
Business Intelligence Portfolio
Chris Seebacher
 

Similar to 3 indexes (20)

Stop the Chaos! Get Real Oracle Performance by Query Tuning Part 2
Stop the Chaos! Get Real Oracle Performance by Query Tuning Part 2Stop the Chaos! Get Real Oracle Performance by Query Tuning Part 2
Stop the Chaos! Get Real Oracle Performance by Query Tuning Part 2
 
Part5 sql tune
Part5 sql tunePart5 sql tune
Part5 sql tune
 
Don't Do This [FOSDEM 2023]
Don't Do This [FOSDEM 2023]Don't Do This [FOSDEM 2023]
Don't Do This [FOSDEM 2023]
 
Powerful Spatial Features You Never Knew Existed in Oracle Spatial and Graph ...
Powerful Spatial Features You Never Knew Existed in Oracle Spatial and Graph ...Powerful Spatial Features You Never Knew Existed in Oracle Spatial and Graph ...
Powerful Spatial Features You Never Knew Existed in Oracle Spatial and Graph ...
 
MySQL best practices at Trovit
MySQL best practices at TrovitMySQL best practices at Trovit
MySQL best practices at Trovit
 
Goldilocks and the Three MySQL Queries
Goldilocks and the Three MySQL QueriesGoldilocks and the Three MySQL Queries
Goldilocks and the Three MySQL Queries
 
Get up to Speed (Quick Guide to data.table in R and Pentaho PDI)
Get up to Speed (Quick Guide to data.table in R and Pentaho PDI)Get up to Speed (Quick Guide to data.table in R and Pentaho PDI)
Get up to Speed (Quick Guide to data.table in R and Pentaho PDI)
 
San diegophp
San diegophpSan diegophp
San diegophp
 
Teradata Aggregate Join Indices And Dimensional Models
Teradata Aggregate Join Indices And Dimensional ModelsTeradata Aggregate Join Indices And Dimensional Models
Teradata Aggregate Join Indices And Dimensional Models
 
15 Ways to Kill Your Mysql Application Performance
15 Ways to Kill Your Mysql Application Performance15 Ways to Kill Your Mysql Application Performance
15 Ways to Kill Your Mysql Application Performance
 
Salesforce integration questions
Salesforce integration questionsSalesforce integration questions
Salesforce integration questions
 
MySQL Performance Optimization
MySQL Performance OptimizationMySQL Performance Optimization
MySQL Performance Optimization
 
DN 2017 | Reducing pain in data engineering | Martin Loetzsch | Project A
DN 2017 | Reducing pain in data engineering | Martin Loetzsch | Project ADN 2017 | Reducing pain in data engineering | Martin Loetzsch | Project A
DN 2017 | Reducing pain in data engineering | Martin Loetzsch | Project A
 
Business Intelligence Portfolio
Business Intelligence PortfolioBusiness Intelligence Portfolio
Business Intelligence Portfolio
 
Apache Impala (incubating) 2.5 Performance Update
Apache Impala (incubating) 2.5 Performance UpdateApache Impala (incubating) 2.5 Performance Update
Apache Impala (incubating) 2.5 Performance Update
 
Hug meetup impala 2.5 performance overview
Hug meetup impala 2.5 performance overviewHug meetup impala 2.5 performance overview
Hug meetup impala 2.5 performance overview
 
MySQL Query Tuning for the Squeemish -- Fossetcon Orlando Sep 2014
MySQL Query Tuning for the Squeemish -- Fossetcon Orlando Sep 2014MySQL Query Tuning for the Squeemish -- Fossetcon Orlando Sep 2014
MySQL Query Tuning for the Squeemish -- Fossetcon Orlando Sep 2014
 
My SQL Skills Killed the Server
My SQL Skills Killed the ServerMy SQL Skills Killed the Server
My SQL Skills Killed the Server
 
Sql killedserver
Sql killedserverSql killedserver
Sql killedserver
 
Data Modeling, Normalization, and De-Normalization | PostgresOpen 2019 | Dimi...
Data Modeling, Normalization, and De-Normalization | PostgresOpen 2019 | Dimi...Data Modeling, Normalization, and De-Normalization | PostgresOpen 2019 | Dimi...
Data Modeling, Normalization, and De-Normalization | PostgresOpen 2019 | Dimi...
 

More from Ram Kedem

More from Ram Kedem (20)

Impala use case @ edge
Impala use case @ edgeImpala use case @ edge
Impala use case @ edge
 
Advanced SQL Webinar
Advanced SQL WebinarAdvanced SQL Webinar
Advanced SQL Webinar
 
Managing oracle Database Instance
Managing oracle Database InstanceManaging oracle Database Instance
Managing oracle Database Instance
 
Power Pivot and Power View
Power Pivot and Power ViewPower Pivot and Power View
Power Pivot and Power View
 
Data Mining in SSAS
Data Mining in SSASData Mining in SSAS
Data Mining in SSAS
 
Data mining In SSAS
Data mining In SSASData mining In SSAS
Data mining In SSAS
 
SQL Injections - Oracle
SQL Injections - OracleSQL Injections - Oracle
SQL Injections - Oracle
 
SSAS Attributes
SSAS AttributesSSAS Attributes
SSAS Attributes
 
SSRS Matrix
SSRS MatrixSSRS Matrix
SSRS Matrix
 
DDL Practice (Hebrew)
DDL Practice (Hebrew)DDL Practice (Hebrew)
DDL Practice (Hebrew)
 
DML Practice (Hebrew)
DML Practice (Hebrew)DML Practice (Hebrew)
DML Practice (Hebrew)
 
Exploring Oracle Database Architecture (Hebrew)
Exploring Oracle Database Architecture (Hebrew)Exploring Oracle Database Architecture (Hebrew)
Exploring Oracle Database Architecture (Hebrew)
 
Introduction to SQL
Introduction to SQLIntroduction to SQL
Introduction to SQL
 
Introduction to Databases
Introduction to DatabasesIntroduction to Databases
Introduction to Databases
 
Deploy SSRS Project - SQL Server 2014
Deploy SSRS Project - SQL Server 2014Deploy SSRS Project - SQL Server 2014
Deploy SSRS Project - SQL Server 2014
 
Pig - Processing XML data
Pig - Processing XML dataPig - Processing XML data
Pig - Processing XML data
 
SSAS Cubes & Hierarchies
SSAS Cubes & HierarchiesSSAS Cubes & Hierarchies
SSAS Cubes & Hierarchies
 
SSRS Basic Parameters
SSRS Basic ParametersSSRS Basic Parameters
SSRS Basic Parameters
 
SSRS Gauges
SSRS GaugesSSRS Gauges
SSRS Gauges
 
SSRS Conditional Formatting
SSRS Conditional FormattingSSRS Conditional Formatting
SSRS Conditional Formatting
 

Recently uploaded

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 

Recently uploaded (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 

3 indexes

  • 2. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Internal fragmentation •When records are stored non-contiguously inside the page, then it is called internal fragmentation. •In other words, internal fragmentation is said to occur if there is unused space between records in a page. •This fragmentation occurs through the process of data modifications (INSERT, UPDATE, and DELETE statements) that are made against the table and therefore, to the indexes defined on the table. •As these modifications are not equally distributed among the rows of the table and indexes, the fullness of each page can vary over time. •This unused space causes poor cache utilization and more I/O, which ultimately leads to poor query performance.
  • 3. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent External Fragmentation •When on disk, the physical storage of pages and extents is not contiguous. •When the extents of a table are not physically stored contiguously on disk, switching from one extent to another causes higher disk rotations.
  • 4. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Identify Fragmentation – Demo 1 -- 1. Identify the object using sys.indexes and sys.objects USE Northwind; GO SELECT * FROM sys.objects WHERE name = 'Products' SELECT * FROM sys.indexes WHERE object_id = object_id('products')
  • 5. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Identify Fragmentation – Demo 1 -- 2. Query the index physical stats DMV using sys.dm_db_index_physical_stats -- The procedure gets the following parameters -- 1. Database ID -- 2. Object ID (the table) -- 3. Index ID -- 4. Partition ID (if needed) -- 5. Scope of detail (LIMITED , SAMPLED , DETAILED) SELECT index_id,index_type_desc, index_level, avg_fragmentation_in_percent AS 'external fragmentation', avg_page_space_used_in_percent AS 'internal fragmentation', page_count FROM sys.dm_db_index_physical_stats(DB_ID(),533576939,NULL,NULL,'DETAILED');
  • 6. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Identify Fragmentation – Demo 1 -- or DECLARE @object_id int SELECT @object_id = object_id FROM sys.objects WHERE name = 'Products' SELECT index_id,index_type_desc, index_level, avg_fragmentation_in_percent AS 'external fragmentation', avg_page_space_used_in_percent AS 'internal fragmentation', page_count FROM sys.dm_db_index_physical_stats(DB_ID(),@object_id,NULL,NULL,'DETAILED');
  • 7. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Identify Fragmentation – Demo 1 SELECT name FROM sys.indexes WHERE object_id = object_id('products') AND index_id = 2 ALTER INDEX CategoriesProducts ON products REBUILD
  • 8. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent External / Internal Fragmentation •External Fragmentation - Aim lower than 10% •avg_fragmentation_in_percent: This is a percentage value that represents external fragmentation. •The lower this value, the better it is. If this value is higher than 10%, some corrective action should be taken. •Internal Fragmentation - Aim higher than 75% •avg_page_space_used_in_percent: This is an average percentage use of pages that represents to internal fragmentation. •Higher the value, the better it is. If this value is lower than 75%, some corrective action should be taken. •If an index is below a certain size, defragmentation doesn't end up doing anything. •In some cases the index is tiny, so fragmentation doesn't matter and won't get defragmented anyway.
  • 9. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Numeric Index Data •Numeric •Indexes with numeric keys work efficiently •Integer types are the most efficient (Exact numeric types) •Approximate data types (float and real) much less efficient CREATE TABLE test_tbl (numeric_col int) CREATE INDEX numeric_col_ix ON test_tbl(numeric_col) DROP INDEX test_tbl.numeric_col_ix DROP TABLE test_tbl
  • 10. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Date Index Data •Date-Related Index Data •Date data types are generally good candidates for index keys •Only slightly less efficient than integer data •date (Accuracy of 1 day) more efficient than datetime (Accuracy of 3.33 milliseconds) CREATE TABLE test_tbl (date_col date) CREATE INDEX date_co_ix ON test_tbl(date_col) DROP INDEX test_tbl.date_co_ix DROP TABLE test_tbl
  • 11. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Character Index Data •Character data types are much less efficient when used in index keys •Character values tend to be much larger than numeric values CREATE TABLE test_tbl (char_col int) CREATE INDEX char_col_ix ON test_tbl(char_col) DROP INDEX test_tbl.char_col_ix DROP TABLE test_tbl
  • 12. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent GUID Index Data CREATE TABLE test_tbl (product_id UNIQUEIDENTIFIER , product_name varchar(25)) CREATE INDEX product_id_ix ON test_tbl(product_id) DROP INDEX test_tbl.product_id_ix DROP TABLE test_tbl
  • 13. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Computed Column and Indexes DROP TABLE computed_tbl ; GO CREATE TABLE computed_tbl (id int, -- date_col AS RAND() PERSISTED -- Since it's not a deterministic function it cannot be PERSISTED rand_col AS RAND(), id_col AS (id+1) PERSISTED , decimal_col DECIMAL(3, 1)); GO INSERT INTO computed_tbl (id, decimal_col) VALUES (1 , 2.1),(2, 3.4),(NULL, 4.7) -- Values computed every select SELECT * FROM computed_tbl -- The expressions must be deterministic ---------------------------------------- CREATE INDEX test_ix ON computed_tbl(rand_col) -- Works CREATE INDEX test_ix ON computed_tbl(id_col)
  • 14. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Single Column vs. Composite Indexes -- Single Column ----------------- DROP TABLE test_tbl SELECT productID , CategoryID , UnitPrice INTO test_tbl FROM northwind.dbo.products INSERT INTO test_tbl SELECT CategoryID , UnitPrice FROM test_tbl SELECT COUNT(*) FROM test_tbl SELECT * FROM test_tbl CREATE INDEX prod_id_ix ON test_tbl (productID) CREATE INDEX prod_cat_ix ON test_tbl (CategoryID) SELECT CategoryID FROM test_tbl ORDER BY CategoryID SELECT CategoryID FROM test_tbl ORDER BY CategoryID , productID
  • 15. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Single Column vs. Composite Indexes -- Composite Indexes -------------------- DROP TABLE test_tbl SELECT productID , CategoryID , UnitPrice INTO test_tbl FROM northwind.dbo.products DECLARE @counter INT SET @counter = 1 WHILE (@counter <=12) BEGIN INSERT INTO test_tbl SELECT CategoryID , UnitPrice FROM test_tbl SET @counter = @counter + 1 END SELECT COUNT(*) FROM test_tbl CREATE INDEX prod_id_ix ON test_tbl (CategoryID, productID) SELECT CategoryID, productID FROM test_tbl ORDER BY CategoryID , productID SELECT CategoryID, productID FROM test_tbl ORDER BY productID , CategoryID
  • 16. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Ascending vs. Descending Indexes DROP INDEX test_tbl.prod_id_ix CREATE INDEX prod_id_ix ON test_tbl(productID DESC) SELECT productID FROM test_tbl ORDER BY productID SELECT productID FROM test_tbl ORDER BY productID DESC DROP INDEX test_tbl.prod_id_ix CREATE INDEX prod_id_ix ON test_tbl (CategoryID DESC, productID) SELECT CategoryID FROM test_tbl ORDER BY CategoryID DESC, productID SELECT CategoryID FROM test_tbl ORDER BY CategoryID , productID
  • 17. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Forwarding Points USE tempdb; GO DROP TABLE dbo.PhoneLog -- Step 1: Create a table as a heap CREATE TABLE dbo.PhoneLog ( PhoneLogID int IDENTITY(1,1) NOT NULL, LogRecorded datetime2 NOT NULL, PhoneNumberCalled nvarchar(100) NOT NULL, CallDurationMs int NOT NULL ); GO -- Step 2: Query sys.indexes to view the structure SELECT index_id, index_type_desc, forwarded_record_count, page_count FROM sys.dm_db_index_physical_stats(DB_ID(),object_id('dbo.PhoneLog'),NULL,NULL,'SAMPLED');
  • 18. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Forwarding Points -- Step 3: Query sys.indexes to view the structure SELECT index_id, index_type_desc, forwarded_record_count, page_count FROM sys.dm_db_index_physical_stats(DB_ID(),object_id('dbo.PhoneLog'), NULL,NULL,'SAMPLED'); -- Step 4: Insert some data into the table SET NOCOUNT ON; DECLARE @Counter int = 0; WHILE @Counter < 1000 BEGIN INSERT dbo.PhoneLog (LogRecorded, PhoneNumberCalled, CallDurationMs) VALUES(SYSDATETIME(),'999-9999',CAST(RAND() * 1000 AS int)); SET @Counter += 1; END; GO
  • 19. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Forwarding Points SELECT * FROM dbo.PhoneLog SELECT index_id, index_type_desc, forwarded_record_count, page_count FROM sys.dm_db_index_physical_stats(DB_ID(),object_id('dbo.PhoneLog'),NULL,NULL,'SAMPLED');
  • 20. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Forwarding Points -- Step 5: Modify the data in the table using replicate SET NOCOUNT ON; DECLARE @Counter int = 0; WHILE @Counter < 1000 BEGIN UPDATE dbo.PhoneLog SET PhoneNumberCalled = REPLICATE('9',CAST(RAND() * 100 AS int)) WHERE PhoneLogID = @Counter; IF @Counter % 100 = 0 PRINT @Counter; SET @Counter += 1; END; GO -- Step 6: Check the level of fragmentation via sys.dm_db_index_physical_stats SELECT * FROM dbo.PhoneLog SELECT index_id, index_type_desc, forwarded_record_count, page_count FROM sys.dm_db_index_physical_stats(DB_ID(),object_id('dbo.PhoneLog'),NULL,NULL,'SAMPLED'); -- Step 8: Rebuild the table ALTER TABLE dbo.PhoneLog REBUILD; GO
  • 21. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Create Clustered Indexes -- 1. Can be created by specifying PRIMARY KEY on table, when creating it CREATE TABLE dbo.Article ( ArticleID int IDENTITY(1,1) PRIMARY KEY, ArticleName nvarchar(50) NOT NULL, PublicationDate date NOT NULL ); -- 2. Can be created by specifying PRIMARY KEY on table, when altering it CREATE TABLE dbo.LogData ( LogID int IDENTITY(1,1), LogData xml NOT NULL ); ALTER TABLE dbo.LogData ADD CONSTRAINT PK_LogData PRIMARY KEY (LogId);
  • 22. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Create Clustered Indexes -- 3. You can add the term NONCLUSTERED to the definition of the PRIMARY KEY -- to avoid this behavior if you wish CREATE TABLE emps1 (empid int PRIMARY KEY NONCLUSTERED , empName varchar(30)) -- 3. Can be created directly CREATE TABLE emps2 (empid int, empName varchar(30)) CREATE CLUSTERED INDEX CL_empid ON dbo.emps2(empName); -- View the different table types SELECT tab.object_id , tab.name AS 'TableName' , i.type_desc , i.name AS 'IndexName' FROM sys.indexes i, sys.tables tab WHERE i.object_id = tab.object_id
  • 23. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Drop Clustered Indexes DROP INDEX CL_empid ON dbo.emps2; ALTER TABLE dbo.Article DROP CONSTRAINT PK__Article__9C6270C8C831D6B7;
  • 24. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Altering a Clustered Index •Index Rebuild : This process drops the existing Index and Recreates the index. •Index Reorganize : This process physically reorganizes the leaf nodes of the index. •Recommendation: •Index should be rebuild when index fragmentation is great than 40%. •Index should be reorganized when index fragmentation is between 10% to 40%. •Index rebuilding process uses more CPU and it locks the database resources. •SQL Server development version and Enterprise version has option ONLINE, which can be turned on when Index is rebuilt. ONLINE option will keep index available during the rebuilding.
  • 25. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Altering a Clustered Index -- Rebuild ALTER INDEX PK_LogData ON dbo.LogData REBUILD; -- Disable ALTER INDEX PK_LogData ON dbo.LogData DISABLE; SELECT name , is_disabled FROM sys.indexes WHERE name = 'PK_LogData' -- Reorginize / Rebuild ALTER INDEX PK_LogData ON dbo.LogData REORGANIZE; ALTER INDEX PK_LogData ON dbo.LogData REBUILD;
  • 26. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Fill Factor DROP TABLE emps3 GO CREATE TABLE emps3 (empid int CONSTRAINT emp3_id_pk PRIMARY KEY WITH (FILLFACTOR = 70), empname varchar(25)) ALTER INDEX emp3_id_pk ON emps3 REBUILD WITH (FILLFACTOR = 80) GO
  • 27. Heap Table Vs. Clustered Index In Depth
  • 28. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Heap Table DROP TABLE dummyTable1 CREATE TABLE DummyTable1 (EmpId Int, EmpName Varchar(8000)) Insert Into DummyTable1 Values (4, Replicate ('d',2000)) Insert Into DummyTable1 Values (6, Replicate ('f',2000)) Insert Into DummyTable1 Values (1, Replicate ('a',2000)) Insert Into DummyTable1 Values (3, Replicate ('c',2000)) Insert Into DummyTable1 Values (10, Replicate ('j',2000)) Insert Into DummyTable1 Values (2, Replicate ('b',2000)) Insert Into DummyTable1 Values (5, Replicate ('e',2000)) Insert Into DummyTable1 Values (8, Replicate ('h',2000)) Insert Into DummyTable1 Values (9, Replicate ('i',2000)) Insert Into DummyTable1 Values (7, Replicate ('g',2000)) Select EmpID From DummyTable1 GO -- Allow DBCC return info back to your session DBCC TRACEON(3604) GO
  • 29. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Heap Table -- 2. View page allocations Declare @DBID Int, @TableID Int Select @DBID = db_id(), @TableID = object_id('DummyTable1') DBCC ind(@DBID, @TableID, -1) GO --PagePID is the physical page numbers used to store the table. In this case, three pages are --currently used to store the data. --IndexID is the type of index,Where: -- 0 – Datapage -- 1 – Clustered Index -- 2 – Greater and equal to 2 is an Index page (Non-Clustered Index and ordinary index), -- PageType tells you what kind of data is stored in each database, Where: -- 10 – IAM (Index Allocation MAP) -- 1 – Datapage -- 2 – Index page -- View each page contents Declare @DBID Int Select @DBID = db_id() DBCC page(@DBID, 1, 304, 3) GO
  • 30. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Nonclustred index CREATE UNIQUE NONCLUSTERED INDEX DummyTable1_empid ON DummyTable1 (empid) GO Declare @DBID Int, @TableID Int Select @DBID = db_id(), @TableID = object_id('DummyTable1') DBCC ind(@DBID, @TableID, -1) GO -- View index page contents Declare @DBID Int Select @DBID = db_id() DBCC page(@DBID, 1, 312, 3) GO
  • 31. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Clustered index DROP TABLE dummyTable2 CREATE TABLE DummyTable2 (EmpId Int Primary Key, EmpName Varchar(8000)) Insert Into DummyTable2 Values (4, Replicate ('d',2000)) Insert Into DummyTable2 Values (6, Replicate ('f',2000)) Insert Into DummyTable2 Values (1, Replicate ('a',2000)) Insert Into DummyTable2 Values (3, Replicate ('c',2000)) Insert Into DummyTable2 Values (10, Replicate ('j',2000)) Insert Into DummyTable2 Values (2, Replicate ('b',2000)) Insert Into DummyTable2 Values (5, Replicate ('e',2000)) Insert Into DummyTable2 Values (8, Replicate ('h',2000)) Insert Into DummyTable2 Values (9, Replicate ('i',2000)) Insert Into DummyTable2 Values (7, Replicate ('g',2000)) Select EmpID From DummyTable2 GO
  • 32. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Clustered index Declare @DBID Int, @TableID Int Select @DBID = db_id(), @TableID = object_id('DummyTable2') DBCC ind(@DBID, @TableID, -1) GO -- Possible to use this undocumented command to see page contents Declare @DBID Int Select @DBID = db_id() DBCC page(@DBID, 1, 317, 3) GO Declare @DBID Int, @TableID Int Select @DBID = db_id(), @TableID = object_id('DummyTable1') DBCC ind(@DBID, @TableID, -1) GO Declare @DBID Int Select @DBID = db_id() DBCC page(@DBID, 1, 286, 3) GO
  • 33. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Clustered index (with secondary index) DROP TABLE dummyTable2 CREATE TABLE DummyTable2 (EmpId Int Primary Key, EmpName Varchar(8000), emp_lName varchar(10)) Insert Into DummyTable2 Values (4, Replicate ('d',2000), Replicate ('d',3)) Insert Into DummyTable2 Values (6, Replicate ('f',2000), Replicate ('f',3)) Insert Into DummyTable2 Values (1, Replicate ('a',2000), Replicate ('a',3)) Insert Into DummyTable2 Values (3, Replicate ('c',2000), Replicate ('c',3)) Insert Into DummyTable2 Values (10, Replicate ('j',2000), Replicate ('j',3)) Insert Into DummyTable2 Values (2, Replicate ('b',2000), Replicate ('b',3)) Insert Into DummyTable2 Values (5, Replicate ('e',2000), Replicate ('e',3)) Insert Into DummyTable2 Values (8, Replicate ('h',2000), Replicate ('h',3)) Insert Into DummyTable2 Values (9, Replicate ('i',2000), Replicate ('i',3)) Insert Into DummyTable2 Values (7, Replicate ('g',2000), Replicate ('g',3)) CREATE UNIQUE NONCLUSTERED INDEX DummyTable2_lname ON DummyTable2 (emp_lName) GO
  • 34. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent Clustered index (with secondary index) Select EmpID From DummyTable2 GO Declare @DBID Int, @TableID Int Select @DBID = db_id(), @TableID = object_id('DummyTable2') DBCC ind(@DBID, @TableID, -1) GO -- Possible to use this undocumented command to see page contents Declare @DBID Int Select @DBID = db_id() DBCC page(@DBID, 1, 292, 3) GO UPDATE DummyTable2 SET EmpId = 100 WHERE EmpId = 1