Why Table Variables are better than Temporary Tables
If you are working with SQL Server tables that have millions of rows, one common technique to speed up your SQL queries and stored procedures is to either use temporary tables or table variables. There is quite a bit of debate on which is the better option, Table Variables or Temporary Tables. We will take a closer look at the two objects with SQL Profiler to decide the winner.Temporary tables
Temporary tables are similar to static tables, however they are not permanent database objects. Temporary tables are extremely useful as work tables for storing intermediate results and complex queries. In addition, SQL server creates and maintains them in Tempdb database and drops them when they are no longer needed. You can virtually do everything with a temporary table that you can do with a standard SQL Server table. You can create indexes, create defaults, modify the table and basically use the temporary table anywhere you need to use a regular persistent database table. Temporary tables can also be used in stored procedures to improve performance tuning and query optimization. There are two types of temporary tables:
Local Temporary table:
This is by far the most common type of a temporary table. When using this one, the scope of the temporary table is limited to the database connection that creates the temp table. The name of the local temporary table must start with a # (Hash symbol) e.g. #local_temp_table. The local temporary table can either be dropped explicitly (best practice), or when the database connection closes. If you are using a store procedure, the local temporary table will be dropped when the stored procedure ends execution.Global Temporary table:
Temporary tables can also be shared across many connections in SQL Server. This is possible by using a global temporary table which is visible to any and all connection in SQL server. This table is only deleted when the last connection explicit drops the temporary tables. Global temporary table must begin with 2 ## signs, e.g.##global_temp_table.Let us take a look at some of these examples next, we are going to be using Northwind database which is a sample database for SQL server. If you would like to download this database, please visit the Northwind download page.
--Create Table #CUSTOMER_DATA
CREATE TABLE #CUSTOMER_DATA
( [CONTACTNAME] [NVARCHAR](30) NULL,
[ADDRESS] [NVARCHAR](60) NULL,
[CITY] [NVARCHAR](15) NULL,
[COUNTRY] [NVARCHAR](15) NULL,
)
We will compare the performance of temporary table with a table variable using SQL Server 2008 at the end of this article
-It is possible to create an index on a temporary table
-You can create constraints on a temporary table including Primary Key, unique, NULL and check constraints
-The scope of a temporary table is not only limited to the current session, instead you can extend it to all connections using global temporary table
-Using Statistics is possible on a temporary table
-Temporary table are best suited for big datasets which involves large amount of processing
-For smaller data sets, temporary table are outperformed by table variables
-Generally there is more overhead with temporary table as you have to create the object, populate temporary table and also log read/write operations
-When using temporary table in a stored procedure, there may be incidence of recompilation
1. Temporary table without an index
2. Temporary table with an index
3. Table Variable
Here we have included a transact sql script for testing the first case. It does the following things:
-Clear the data and procedure cache to get a clean baseline
-Create the temporary table
-Populate the temporary table
-Run a select query from the temporary table with formatted customer mailing list
USE Northwind
--TEMP TABLE WITH NO INDEX
--The first command empties the data cache and the second one empties the procedure cache
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
--This displays disk activity and time of TSQL execution
SET STATISTICS IO ON
SET STATISTICS TIME ON
--Create Table #CUSTOMER_DATA
CREATE TABLE #CUSTOMER_DATA
( [CONTACTNAME] [NVARCHAR](30) NULL,
[ADDRESS] [NVARCHAR](60) NULL,
[CITY] [NVARCHAR](15) NULL,
[COUNTRY] [NVARCHAR](15) NULL,
)
--Populate Temp Table #CUSTOMER_DATA
INSERT INTO #CUSTOMER_DATA
SELECT
CONTACTNAME, ADDRESS, CITY, COUNTRY
FROM DBO.CUSTOMER_DATA_BAK
WHERE CITY IN ('SAN FRANCISCO', 'SEATLLE', 'ELGIN', 'LONDON')
--Select formatted data from Temp Table #CUSTOMER_DATA
SELECT
CONTACTNAME + CHAR(13) + CHAR(10) +
ADDRESS + CHAR(13) + CHAR(10) +
CITY + ' ' + COUNTRY + CHAR(13) + CHAR(10) +
CHAR(13) + CHAR(10)AS PRINT_ADDRESS
FROM #CUSTOMER_DATA
WHERE CITY ='LONDON'
--Explicitly drop the Temp Table #CUSTOMER_DATA
DROP TABLE #CUSTOMER_DATA
/* SQL PROFILER RESULTS
CPU= 3274
READS= 72194
WRITES= 2297
DURATION= 162519
*/
Advantages of using temporary tables
Here are some of the advantages of using temporary tables:-It is possible to create an index on a temporary table
-You can create constraints on a temporary table including Primary Key, unique, NULL and check constraints
-The scope of a temporary table is not only limited to the current session, instead you can extend it to all connections using global temporary table
-Using Statistics is possible on a temporary table
-Temporary table are best suited for big datasets which involves large amount of processing
Disadvantages of using temporary tables
Some of the disadvantages of using temporary tables are:-For smaller data sets, temporary table are outperformed by table variables
-Generally there is more overhead with temporary table as you have to create the object, populate temporary table and also log read/write operations
-When using temporary table in a stored procedure, there may be incidence of recompilation
Performance Testing between Temporary Tables and Table Variables
Using Northwind sample database, we are going to create a test table called CUSTOMER_DATA_BAK which contains repeated data from CUSTOMER_DATA table. This test table has 2 million rows so we can compare temporary table with table variable for a large data set. When we run these sql queries we will run a trace in SQL Profiler to capture different parameters and statistics. We will repeat the test for these scenarios:1. Temporary table without an index
2. Temporary table with an index
3. Table Variable
Here we have included a transact sql script for testing the first case. It does the following things:
-Clear the data and procedure cache to get a clean baseline
-Create the temporary table
-Populate the temporary table
-Run a select query from the temporary table with formatted customer mailing list
USE Northwind
--TEMP TABLE WITH NO INDEX
--The first command empties the data cache and the second one empties the procedure cache
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
--This displays disk activity and time of TSQL execution
SET STATISTICS IO ON
SET STATISTICS TIME ON
--Create Table #CUSTOMER_DATA
CREATE TABLE #CUSTOMER_DATA
( [CONTACTNAME] [NVARCHAR](30) NULL,
[ADDRESS] [NVARCHAR](60) NULL,
[CITY] [NVARCHAR](15) NULL,
[COUNTRY] [NVARCHAR](15) NULL,
)
--Populate Temp Table #CUSTOMER_DATA
INSERT INTO #CUSTOMER_DATA
SELECT
CONTACTNAME, ADDRESS, CITY, COUNTRY
FROM DBO.CUSTOMER_DATA_BAK
WHERE CITY IN ('SAN FRANCISCO', 'SEATLLE', 'ELGIN', 'LONDON')
--Select formatted data from Temp Table #CUSTOMER_DATA
SELECT
CONTACTNAME + CHAR(13) + CHAR(10) +
ADDRESS + CHAR(13) + CHAR(10) +
CITY + ' ' + COUNTRY + CHAR(13) + CHAR(10) +
CHAR(13) + CHAR(10)AS PRINT_ADDRESS
FROM #CUSTOMER_DATA
WHERE CITY ='LONDON'
--Explicitly drop the Temp Table #CUSTOMER_DATA
DROP TABLE #CUSTOMER_DATA
/* SQL PROFILER RESULTS
CPU= 3274
READS= 72194
WRITES= 2297
DURATION= 162519
*/
You can download this sql script on temp table from this location:
When we look at the trace output from the SQL Profiler on temp table, the numbers are as follows:
CPU=3274
READS=72194
WRITES=2297
DURATION=162519
Here is a screen shot from SQL server Profiler trace
http://www.sqlserver2008tutorial.com/blog/temporary-tables/temp-table-profiler.jpg
Performance Testing on Temp Table with an Index
Next we are going to test the same process, however this time we are going to create an index on the temporary table in addition to the existing code. You can download this sql script on temp table with index from this location:
We have included a partial screen shot of this transact sql code when we tested this in Management Studion in SQL Server 2008:
http://www.sqlserver2008tutorial.com/blog/temporary-tables/create-temp-table-index.jpg
When we look at the trace on temp table with an index from the SQL Profiler, here are the numbers:
CPU=6114
READS=757553
WRITES=3035
DURATION=66602
Here is a screen shot from SQL server Profiler trace
http://www.sqlserver2008tutorial.com/blog/temporary-tables/temp-table-index-profiler.jpg
Table variables:
Table variable is simply a data variable of type table. As such Table variables is created using a declare statement. It offers an alternative approach to using temporary table and is typically faster and efficient for smaller record sets. A table variable can store results for later processing similar in concept to using a temporary table. Table variable act like a local variables and their scope ends with the batch that is currently using them.Here is an example of sql code for a Table variable
--Declare Table Variable @CUSTOMER_DATA
DECLARE @CUSTOMER_DATA TABLE
( [CONTACTNAME] [NVARCHAR](30) NULL,
[ADDRESS] [NVARCHAR](60) NULL,
[CITY] [NVARCHAR](15) NULL,
[COUNTRY] [NVARCHAR](15) NULL
)
Advantages of a Table variable
-In general for smaller record set, table variables outperform the temporary tables
-When using a function with temporary storage, you have to use the table variable as temporary tables will not work
-Table variables do not cause recompilation issues like temporary tables do
-Table variables require fewer system resources causing than them to be less of a performance hit compare to temp tables
Disadvantages of a table variable
Here are some of disadvantages of using table variables:
-The table definition cannot be changed once table variable has been declared
-You cannot use Select Into statements with table variables
-The only way you can create an index in a table variable is to use a Primary Key constraint at the time of table variable declaration
-New Indexes cannot be created after declaration of the table variable
-Performance is slow with table variables when working with large data sets
-Rollback Tran and Truncate table are not allowed with table variables
Performance Testing on Table Variable
Next we are going to repeat the process this time with a table variable. Here is the script than we are going to use:USE Northwind
--SQL TABLE VARIABLE
--The first command empties the data cache and the second one empties the procedure cache
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
--This displays disk activity and time of TSQL execution
SET STATISTICS IO ON
SET STATISTICS TIME ON
--Declare Table Variable @CUSTOMER_DATA
DECLARE @CUSTOMER_DATA TABLE
( [CONTACTNAME] [NVARCHAR](30) NULL,
[ADDRESS] [NVARCHAR](60) NULL,
[CITY] [NVARCHAR](15) NULL,
[COUNTRY] [NVARCHAR](15) NULL
)
--Insert data into Table Variable @CUSTOMER_DATA
INSERT INTO @CUSTOMER_DATA
SELECT
CONTACTNAME, ADDRESS, CITY, COUNTRY
FROM DBO.CUSTOMER_DATA_BAK
WHERE CITY IN ('SAN FRANCISCO', 'SEATLLE', 'ELGIN', 'LONDON')
--Select data from Table Variable @CUSTOMER_DATA
SELECT
CONTACTNAME + CHAR(13) + CHAR(10) +
ADDRESS + CHAR(13) + CHAR(10) +
CITY + ' ' + COUNTRY + CHAR(13) + CHAR(10) +
CHAR(13) + CHAR(10)AS PRINT_ADDRESS
FROM @CUSTOMER_DATA
WHERE CITY ='LONDON'
/* SQL PROFILER RESULTS
CPU= 2730
READS= 71000
WRITES= 2289
DURATION= 46184
*/
Next we are going to repeat the process this time with a table variable. Here is the script than we are going to
You can also download the temp variable sql script from our site
We have included a screen shot of the SQL profiler results on table variables
http://www.sqlserver2008tutorial.com/blog/temporary-tables/table-variable-profiler.jpg
When we look at the trace on temp table from the SQL Profiler output, here are the numbers:
CPU=2730
READS=71000
WRITES=2289
DURATION=46184
Performance Testing Results between Temp Table and Table Variable
Parameter | Temp Table (No Index) | Temp Table (With Index) | Table Variable |
CPU | 3274 | 6114 | 2730 |
DURATION | 162519 | 66602 | 46184 |
As you can see using Table Variable is a much better option as it used less CPU and took only 1/3 of time to process the same data!!
For futher query optimization tricks and tips, please visit our site on SQL Server Tutorials
Related Links on the Topic
-Temporary Tables vs. Table Variables-Should I use a #temp table or a @table variable?
No comments:
Post a Comment