Table Variable VS. Temp Table - Execution Plan Differences Explained in Details - Part 1
In the previous post
, we've illustrated the differences between the execution plans generated by joining a table variable and by a temp table. In this post, we are going to look closer about the differences, and get a better understanding about the mechanisms behind those differences.
Let's recap our scripts and their execution plans.
The whole data flow is quite similar between the two:
I've circled the differences between the two screenshots, with two difference colors. The blue circles indicate that different join types (Nested Loop VS Hash Match) are used in the two scripts, resulting in Clustered Index Seek VS Clustered Index Scan respectively as circled in red.
To understand the above differences, you need to know what Nested Loop (NL) and Hash Match (HM) are, and then you'll understand why the Clustered Index Seek (CISK) or Clustered Index Scan (CISN). If you don't, well don't worry because the execution plan itself has already told us enough information for us to understand. If you hover over the first NL from right in the execution plan window, you'll see the below popped information
As highlighted in yellow in the above screenshot, NL scans each row in the outer input - which is the BusinessEntityID column in the table variable @CET - and then scans the inner input (which is the BusinessEntityID column in table Person.BusinessEntity) to find the match, and this is why we see Clustered Index Seek is used as only a range of values is scanned as illustrated below
If we summarise the above analysis, the following conclusions can be made regarding table variable join script:
, we've illustrated the differences between the execution plans generated by joining a table variable and by a temp table. In this post, we are going to look closer about the differences, and get a better understanding about the mechanisms behind those differences.
Let's recap our scripts and their execution plans.
DECLARE @CET TABLE
(
[BusinessEntityID] int
,[AddressID] int
,[AddressTypeID] int
,[Name] [nvarchar](50)
)
INSERT INTO @CET
SELECT
BEA.BusinessEntityID
,BEA.AddressID
,BEA.AddressTypeID
,ADT.Name
FROM [Person].[BusinessEntityAddress]
BEA
INNER JOIN [Person].[AddressType] ADT ON BEA.AddressTypeID = ADT.AddressTypeID
SELECT
CS.BusinessEntityID
,CS.AddressID
,CS.AddressTypeID
,BE.ModifiedDate
,AD.AddressLine1
,AD.AddressLine2
,AD.City
,Ad.PostalCode
,AD.StateProvinceID
,CS.Name
FROM @CET CS
INNER JOIn [Person].[BusinessEntity] BE ON CS.BusinessEntityID = BE.BusinessEntityID
INNER JOIN [Person].[Address] AD ON CS.AddressID = AD.AddressID
SELECT
BEA.BusinessEntityID
,BEA.AddressID
,BEA.AddressTypeID
,ADT.Name
INTO #CTE
FROM [Person].[BusinessEntityAddress]
BEA
INNER JOIN [Person].[AddressType] ADT ON BEA.AddressTypeID = ADT.AddressTypeID
SELECT
CS.BusinessEntityID
,CS.AddressID
,CS.AddressTypeID
,BE.ModifiedDate
,AD.AddressLine1
,AD.AddressLine2
,AD.City
,Ad.PostalCode
,AD.StateProvinceID
,CS.Name
FROM #CTE CS
INNER JOIn [Person].[BusinessEntity] BE ON CS.BusinessEntityID = BE.BusinessEntityID
INNER JOIN [Person].[Address] AD ON CS.AddressID = AD.AddressID
The whole data flow is quite similar between the two:
- The table variable or temp table is used to join the table Person.BusinessEntity.
- The above result is used to join table Person.Address.
I've circled the differences between the two screenshots, with two difference colors. The blue circles indicate that different join types (Nested Loop VS Hash Match) are used in the two scripts, resulting in Clustered Index Seek VS Clustered Index Scan respectively as circled in red.
To understand the above differences, you need to know what Nested Loop (NL) and Hash Match (HM) are, and then you'll understand why the Clustered Index Seek (CISK) or Clustered Index Scan (CISN). If you don't, well don't worry because the execution plan itself has already told us enough information for us to understand. If you hover over the first NL from right in the execution plan window, you'll see the below popped information
As highlighted in yellow in the above screenshot, NL scans each row in the outer input - which is the BusinessEntityID column in the table variable @CET - and then scans the inner input (which is the BusinessEntityID column in table Person.BusinessEntity) to find the match, and this is why we see Clustered Index Seek is used as only a range of values is scanned as illustrated below
If we summarise the above analysis, the following conclusions can be made regarding table variable join script:
- A NL is committed between @CTE and Person.BusinessEntity. A table scan is conducted on @CTE as it's a heap table, and for each row in the column BusinessEntityID, the same column in table Person.BusinessEntity is scanned to output the matching rows.
- Based on the above output, for each row of the AddressID column in @CTE, the same column in table Person.Address is scanned to output the matching rows.
Comments
Post a Comment