Contenu connexe
Similaire à 4 execution plans (20)
4 execution plans
- 2. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Display Estimated Execution Plan
Display EEP
•First time for query number 1
•Second time for query number 2
•Third time for both of them - which cost is cheaper and why ?
•You can use CTRL-L as a shortcut to Display Estimated Execution Plan
SELECT ProductID, Name, Color
FROM Production.Product
WHERE Color IN ('Blue','Red')
ORDER BY Name;
GO
SELECT ProductID, Name, Color
FROM Production.Product
WHERE Color IN ('Blue','Red')
ORDER BY ProductID;
GO
- 3. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Display Estimated Execution Plan
Display EEP
•First time for CREATE TABLE
•Second time for INSERT, is it possible ?
•Third time for both of them, again - is it possible ?
CREATE TABLE SomeTable
( SomeTableID INT IDENTITY(1, 1) PRIMARY KEY,
FullName varchar(35))
INSERT INTO SomeTable VALUES('Hello'),('There');
SELECT * FROM SomeTable;
DROP TABLE SomeTable;
GO
- 4. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Display Estimated Execution Plan
•Review the following tables :
SELECT * FROM [Production].[Product]
SELECT * FROM [Production].[ProductModel]
•Display Estimated Execution Plan
•First time for query number 1
•Second time for query number 2
•Now use the estimated execution plan to compare two queries, How do you explain that such different queries return the same plan?
SELECT p.ProductID, p.Name, p.Color, p.Size
FROM Production.Product AS p
LEFT OUTER JOIN Production.ProductModel AS pm
ON p.ProductModelID = pm.ProductModelID
WHERE pm.ProductModelID IS NOT NULL;
GO
SELECT p.ProductID, p.Name, p.Color, p.Size
FROM Production.Product AS p
WHERE EXISTS(SELECT 1 FROM Production.ProductModel AS pm
WHERE p.ProductModelID = pm.ProductModelID);
GO
- 5. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Include Actual Execution Plan
•Execute the query and include Actual Execution Plan
•Shortcut for Include Actual Execution Plan : CTRL + M
SELECT ProductID, Name, Color
FROM Production.Product
WHERE Color IN ('Blue','Red')
ORDER BY Name;
GO
•Save EP & Show EP as XML
•Right-click on the plan and choose "Save Execution Plan As"
•Right-click on the plan and choose "Show Execution Plan XML"
- 6. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
SET SHOWPLAN_TEXT ON / OFF
•Causes Microsoft® SQL Server™ not to execute Transact-SQL statements. Instead, SQL Server returns detailed information about how the statements are executed.
•Can be executed via SSMS or SQLCMD
•In order to use SQLCMD from command prompt type -SQLCMD -S <server name>/<instance name) for example : sqlcmd -S WIN-48RSPI12UJHINST01
USE AdventureWorks2012;
GO
SET SHOWPLAN_TEXT ON;
GO
SELECT *
FROM Production.Product
WHERE ProductID = 905;
GO
SET SHOWPLAN_TEXT OFF;
GO
- 7. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
SET SHOWPLAN_ALL ON / OFF
•Causes Microsoft SQL Server not to execute Transact-SQL statements. Instead, SQL Server returns detailed information about how the statements are executed and provides estimates of the resource requirements for the statements
•Can be executed via SSMS or SQLCMD
•In order to use SQLCMD from command prompt type - SQLCMD -S <server name>/<instance name) for example : sqlcmd -S WIN-48RSPI12UJHINST01
USE AdventureWorks2012;
GO
SET SHOWPLAN_ALL ON;
GO
SELECT *
FROM Production.Product
WHERE ProductID = 905;
GO
SET SHOWPLAN_ALL OFF;
GO
- 9. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Heap Table
•Full Table Scan
•Non Clustered Index Seek
•Non Clustered Index Scan
SELECT * FROM sys.indexes WHERE object_id = object_id ('dbo.DatabaseLog')
-- 1. Full Table Scan
---------------------
SELECT * FROM dbo.DatabaseLog;
GO
SELECT * FROM dbo.DatabaseLog WHERE event = 'ALTER_TABLE'
-- 2. Non Clustered Index Seek
------------------------------------------
-- retrieves selective rows from the table
SELECT * FROM dbo.DatabaseLog WHERE DatabaseLogID = 1 ;
GO
-- 3. Non Clustered Index Scan
-------------------------------------- -
-- retrieves all the rows from the index
SELECT DatabaseLogID From DatabaseLog
- 10. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Clustered Index
•Clustered Index Scan
•Clustered Index Seek
•Non Clustered Index Seek
•Non Clustered Index Scan
SELECT * FROM sys.indexes WHERE object_id = object_id ('Person.ContactType')
-- 1. Clustered Index Scan
---------------------------------------
-- retrieves all the rows from the table
SELECT * FROM Person.ContactType;
GO
-- 2. Clustered Index Seek
------------------------------------------
-- retrieves selective rows from the table
SELECT * FROM Person.ContactType WHERE [ContactTypeID] = 12;
GO
SELECT * FROM Person.ContactType WHERE [ContactTypeID] BETWEEN 10 AND 20;
GO
- 11. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Clustered Index
-- 3. Non Clustered Index Seek
------------------------------------------
-- retrieves selective rows from the table
SELECT * FROM Person.ContactType WHERE [Name] = 'some value';
GO
-- 4. Non Clustered Index Scan
----------------------------------------
-- retrieves all the rows from the index
SELECT [Name] FROM Person.ContactType ;
GO
- 12. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Sort Operations
SELECT * FROM sys.indexes WHERE object_id = object_id ('Production.ProductInventory')
-- Compare the different queries and note the costs :
SELECT *
FROM Production.ProductInventory
ORDER BY Shelf;
GO
SELECT *
FROM Production.ProductInventory
ORDER BY [ProductID] , [LocationID];
GO
SELECT *
FROM Production.ProductInventory
ORDER BY [LocationID] , [ProductID] ;
GO
- 13. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Merge Join VS. Hash Join VS. Nested Loop
--------------------------------------------------------------------------------------------
-- Test 1, Big Table
--------------------------------------------------------------------------------------------
DROP TABLE tableA
GO
DROP TABLE tableB
GO
create table tableA (id int identity ,name varchar(50))
declare @i int
set @i=0
while (@i<100)
begin
insert into tableA (name)
select name from master.dbo.spt_values
set @i=@i+1
end
go
select COUNT(*) from dbo.tableA --251500
- 14. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Merge Join VS. Hash Join VS. Nested Loop
create table tableB (id int identity ,name varchar(50))
declare @i int
set @i=0
while (@i<100)
begin
insert into tableB (name)
select name from master.dbo.spt_values
set @i=@i+1
end
select COUNT(*) from dbo.tableB --251500
SELECT TOP(10) * FROM dbo.tableB
SELECT TOP(10) * FROM dbo.tableA
select TOP(10) * from dbo.tableA A join tableB B
on (a.id=b.id)
select COUNT(*) from dbo.tableA A join tableB B
on (a.id=b.id)
- 15. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Merge Join VS. Hash Join VS. Nested Loop
-----------------------------------------------------
-- Test 1A - Both tables dont have index - Hash Join
-----------------------------------------------------
-- Check Excecution Plan
select * from dbo.tableA A join tableB B
on (a.id=b.id)
-----------------------------------------------------
-- Test 1B - One table have index - Hash Join
-----------------------------------------------------
create unique clustered index cx_tableA on tableA (id)
-- Check Excecution Plan again
select * from dbo.tableA A join tableB B
on (a.id=b.id)
-----------------------------------------------------
-- Test 1C - Both tables have index - Merge Join
-----------------------------------------------------
create unique clustered index cx_tableB on tableB (id)
-- Check Excecution Plan again
select * from dbo.tableA A join tableB B
on (a.id=b.id)
- 16. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Merge Join VS. Hash Join VS. Nested Loop
--------------------------------------------------------------------------------------------
-- Test 2, Medium Table
--------------------------------------------------------------------------------------------
DROP TABLE tableA
GO
DROP TABLE tableB
GO
create table tableA (id int identity ,name varchar(50))
declare @i int
set @i=0
while (@i<1)
begin
insert into tableA (name)
select name from master.dbo.spt_values
set @i=@i+1
end
go
select COUNT(*) from dbo.tableA --2515
- 17. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Merge Join VS. Hash Join VS. Nested Loop
create table tableB (id int identity ,name varchar(50))
declare @i int
set @i=0
while (@i<1)
begin
insert into tableB (name)
select name from master.dbo.spt_values
set @i=@i+1
end
select COUNT(*) from dbo.tableB --2515
SELECT TOP(10) * FROM dbo.tableB
SELECT TOP(10) * FROM dbo.tableA
select TOP(10) * from dbo.tableA A join tableB B
on (a.id=b.id)
select COUNT(*) from dbo.tableA A join tableB B
on (a.id=b.id)
- 18. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Merge Join VS. Hash Join VS. Nested Loop
-----------------------------------------------------
-- Test 2A - Both tables dont have index - Hash Join
-----------------------------------------------------
-- Check Excecution Plan
select * from dbo.tableA A join tableB B
on (a.id=b.id)
-----------------------------------------------------
-- Test 2B - One table have index - Merge Join
-----------------------------------------------------
create unique clustered index cx_tableA on tableA (id)
-- Check Excecution Plan again
select * from dbo.tableA A join tableB B
on (a.id=b.id)
-----------------------------------------------------
-- Test 2C - Both tables have index - Merge Join
-----------------------------------------------------
create unique clustered index cx_tableB on tableB (id)
-- Check Excecution Plan again
select * from dbo.tableA A join tableB B
on (a.id=b.id)
- 19. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Merge Join VS. Hash Join VS. Nested Loop
--------------------------------------------------------------------------------------------
-- Test 3, Small Table
--------------------------------------------------------------------------------------------
DROP TABLE tableA
GO
DROP TABLE tableB
GO
create table tableA (id int identity ,name varchar(50))
declare @i int
set @i=0
while (@i<1)
begin
insert into tableA (name)
select top (10) name from master.dbo.spt_values
set @i=@i+1
end
go
select COUNT(*) from dbo.tableA --10
- 20. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Merge Join VS. Hash Join VS. Nested Loop
create table tableB (id int identity ,name varchar(50))
declare @i int
set @i=0
while (@i<1)
begin
insert into tableB (name)
select top (10) name from master.dbo.spt_values
set @i=@i+1
end
select COUNT(*) from dbo.tableB --10
SELECT TOP(10) * FROM dbo.tableB
SELECT TOP(10) * FROM dbo.tableA
select TOP(10) * from dbo.tableA A join tableB B
on (a.id=b.id)
select COUNT(*) from dbo.tableA A join tableB B
on (a.id=b.id)
- 21. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Merge Join VS. Hash Join VS. Nested Loop
-----------------------------------------------------
-- Test 3A - Both tables dont have index - Hash Join
-----------------------------------------------------
-- Check Excecution Plan
select * from dbo.tableA A join tableB B
on (a.id=b.id)
-----------------------------------------------------
-- Test 3B - One table have index - Nested Loop
-----------------------------------------------------
create unique clustered index cx_tableA on tableA (id)
-- Check Excecution Plan again
select * from dbo.tableA A join tableB B
on (a.id=b.id)
-----------------------------------------------------
-- Test 3C - Both tables have index - Nested Loop
-----------------------------------------------------
create unique clustered index cx_tableB on tableB (id)
-- Check Excecution Plan again
select * from dbo.tableA A join tableB B
on (a.id=b.id)
- 22. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Join Methods
-- 1. Nested Loops
-------------------
USE Northwind
GO
SELECT COUNT(*) FROM products
SELECT COUNT(*) FROM suppliers
SELECT pro.productName , sup.SupplierID
FROM products pro JOIN suppliers sup
ON pro.SupplierID = sup.SupplierID
-- 2. Hash Join
---------------
USE AdventureWorks2012
GO
SELECT COUNT(*) FROM [Sales].[Customer]
SELECT COUNT(*) FROM [Sales].[Store]
SELECT cust.customerID , st.Name
FROM [Sales].[Customer] cust JOIN [Sales].[Store] st
ON cust.[StoreID] = st.[BusinessEntityID]
SELECT sal.SalesOrderID , sal.OrderQty, prod.Name
FROM Sales.SalesOrderDetail sal JOIN Production.Product prod
ON Sal.ProductID = Prod.ProductID
- 23. Copyright 2014 © Ram Kedem. All rights reserved. Not to be reproduced without written consent
Join Methods
SELECT * FROM Sales.Customer
SELECT * FROM Sales.SalesOrderHeader
-- Hash Join
SELECT c.CustomerID , s.OrderDate
FROM sales.customer c LEFT OUTER JOIN Sales.SalesOrderHeader s
ON c.CustomerID = s.CustomerID;
-- Merge Join
SELECT c.CustomerID
FROM sales.customer c LEFT OUTER JOIN Sales.SalesOrderHeader s
ON c.CustomerID = s.CustomerID;