Note: This is part of a series on Temporary Query Items.
We’ve talked previously about what a Temporary Query Item is and how scope, indexing, statistics, TempDB, and memory can all affect your choice of TQI for your queries. It’s all been important discussion, if a little unsexy – go back and read it if you haven’t, or you may get a little lost. If you have (no really, read it first!), then you’re ready to walk through our first Temporary Query Item – Temporary Tables.
A Little History
Temporary Tables have been present in SQL Server since at least SQL Server 2000. You should be able to make use of them everywhere.
Location, Location, Location
Temporary Tables live in TempDB. This is not necessarily a performance problem, as even objects in TempDB can be cached in memory. However, if too much is going on in TempDB, this can cause a performance loss due to contention. If WAY too much is going on in TempDB, use of a temporary table can actually cause you to blow TempDB, which means your query will fail. Don’t cause your query to fail. Using a temporary table certainly doesn’t guarantee problems, but you do want to be careful.
Regarding location scope, temporary tables give you a little bit of flexibility. You can declare your temporary table as global or local. A global temporary table can be accessed from other connections than the creating one. A local temporary table can only be accessed from the creating connection, although it can be used and reused as long as the connection is open.
Global temporary tables are named with a ## prefix. So, if I want a global temporary table to hold pickles, I would name it ##Pickles. Once created, this table will hang around as long as something is using it, and anyone can make use of it.
Local temporary tables are named with a # prefix. My same temp table for holding delicious pickles would be named #Pickles. Once created, this table can only be accessed from the creating connection. They can create their own #Pickles table for THEIR delicious pickles, because behind the scenes SQL Server will postfix your local temporary table name with a long string of underscores and a hexadecimal number, and postfix theirs with a different long string of underscores and a hexadecimal number. BIG HAIR DEAL: Clustered indexes on local temp tables are global in scope. This means that two or more people attempt to create local temporary tables with identically named clustered indexes, the runner-up loses and cannot create the table.
How Long Does It Live?
Temporary tables present a fair amount of longevity. If SQL Server stops, then your temp table will go away. If you close the creating connection, the temp table will go away. If you drop the temp table, it will also go away. Otherwise, temporary tables will happily sit there forever occupying TempDB. This makes it one of the longest-lived TQIs, which is one of its biggest strengths.
I should note here that if a global temporary table is actively being referenced when dropped or the creating connection is closed, the table will actually persist until it is no longer being actively referenced. This is a little nicer than getting an error because the object suddenly doesn’t exist in the middle of your query. It could also mean that you insert into something that immediately stops existing, though.
Another strength of temporary tables is that they can be indexed. Specifically, temporary tables can have both clustered and nonclustered indexes applied to them. They can also be created with a clustered index already on them. I’ve used this to my advantage before by making a temporary table with a copy of the data I want, then indexing it to fit my series of queries.
When you create a temporary table based on an existing data set, it is created as a separate physical copy of the data. Modifications to the temp table do not affect the original data source. This can be either a strength or a weakness , depending on your purposes for using a TQI.
But Does It Blend?
The data contained within a temporary table is modifiable. You can insert, update, or delete records within. And you can dance if you want to.
As mentioned above, modifications to the temporary table does not automatically translate back to the original data used to populate it.
Show Me The Code!
Test Data Setup
I’ll be using a test table to do some demonstrations. You can create/populate it here:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Temporary tables can be created in a very similar way to plain old tables. You can do a standard create statement:
1 2 3 4 5 6 7 8
As it turns out, you can also do SELECT INTO with a temp table. I’ll show that later.
Inserting into a temporary table is just like regular tables as well.
1 2 3 4 5
Temporary tables are also updateable:
1 2 3 4 5 6 7
You can create indexes on your temp table after the fact. Run the SELECT with the execution plan, create the index, then rerun the SELECT and note the change in execution plan. BIG HAIRY WARNING: If you attempt to create an index on a temp table with the execution plan enabled, SSMS will blow up.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Global vs Local
So far, we’ve been using a global temporary table. Here, we’ll look at local temporary tables – run the CREATE and INSERT in one window, then run the SELECT in another:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3
The temporary table goes away when you close the creating connection. Close your original window, then run this:
1 2 3
Source Data Dependence
And finally, we can see modifying the data in the temporary table is independent of the data that created it. Note the SELECT INTO syntax:
1 2 3 4 5 6 7 8 9
And here’s the cleanup code for this exercise:
In this post, we’ve focused on some of the strengths and weaknesses of temporary tables. While this is not sufficient information to decide that a temporary table would be a more or less advantageous choice of Temporary Query Item in all cases, it should give you some ideas on how to make use of them in your queries. Next up, we’ll take a look at our next TQI: Table Variables.