Programming

When should I use a table variable vs temporary table in sql server

25 September 2026 · 9 min read

When should I use a table variable vs temporary table in sql server

Choosing between table variables and temporary tables in SQL Server can significantly impact query performance. Making the right choice depends on understanding the nuances of each and how they interact with your specific data and query patterns. This post will delve into the details of when to use a table variable versus a temporary table, offering practical guidance backed by expert advice and real-world examples to help you optimize your SQL Server queries.

Scope and Lifetime

Table variables have a limited scope, existing only within the batch or stored procedure where they are declared. They are automatically destroyed when the batch or procedure finishes. Temporary tables, denoted by the or prefix, have a broader scope, persisting across batches within the same connection. Global temporary tables () are even accessible across different connections. This difference in lifespan is a key factor in deciding which to use.

For instance, if you need to pass data between stored procedures within the same connection, a temporary table is necessary. If the data is only required within a single stored procedure, a table variable might suffice. Consider the context of your data usage when making this decision.

Performance Considerations

Performance is often the deciding factor when choosing between table variables and temporary tables. Table variables do not have statistics generated, leading SQL Server to often underestimate the number of rows involved, potentially causing inefficient query plans. Temporary tables, on the other hand, have statistics automatically generated, allowing the optimizer to create more efficient plans, especially for larger datasets.

According to SQL Server expert, Brent Ozar, “Table variables are great for small sets of data, but for anything substantial, temporary tables are usually the better choice due to statistics.” This advice highlights the importance of data size in the decision-making process.

Imagine a scenario where you’re filtering a large table based on a small subset of IDs. Storing these IDs in a temporary table would allow for optimized filtering due to the presence of statistics, whereas a table variable might lead to a suboptimal execution plan.

Memory and Disk Usage

Table variables primarily reside in memory, while temporary tables can spill over to disk if they grow too large. This difference can have performance implications. For smaller datasets that fit comfortably in memory, table variables can offer faster access. However, for larger datasets, temporary tables’ ability to utilize disk space can prevent memory pressure, potentially leading to better overall system performance.

Consider a scenario where you need to store the results of a complex query for later use. If the result set is expected to be large, using a temporary table could be beneficial, allowing it to leverage disk space and avoid memory bottlenecks.

Recompilation and Statistics

One advantage of table variables is that they typically do not cause stored procedure recompilation, whereas schema changes to temporary tables can trigger recompilation. This can be a significant performance factor in frequently executed stored procedures.

If you need a temporary data structure within a stored procedure that is called frequently and performance is critical, consider using a table variable to avoid recompilation overhead.

Practical Examples

  • Scenario 1: Filtering data based on a small list of values – A temporary table is generally preferable due to statistics.
  • Scenario 2: Storing a few rows within a frequently called stored procedure – A table variable is often more efficient.

Infographic Placeholder: Visual comparison of table variables vs. temporary tables.

Best Practices and Recommendations

  1. For small datasets used within a single batch or stored procedure, and when recompilation is a concern, favor table variables.
  2. For larger datasets, or when statistics are crucial for query optimization, opt for temporary tables.
  3. Carefully analyze your specific use case, considering data size, scope, and performance requirements before making a decision. Test both options if necessary to determine the optimal choice.

Choosing between table variables and temporary tables in SQL Server is a nuanced decision that depends on various factors. While table variables excel in limited scopes with small datasets and frequent procedure calls, temporary tables shine with larger datasets needing statistics and cross-batch persistence. By carefully assessing your needs and applying the principles discussed, you can make informed decisions that enhance the efficiency of your SQL Server queries. Learn more about advanced SQL Server techniques by exploring resources like this guide to SQL Server performance tuning. This understanding empowers you to write more efficient, performant queries and optimize your database interactions. Dive deeper into query optimization with resources from authoritative sources like Microsoft Docs and SQL Shack. This will help you make the best decisions for your specific scenarios.

FAQ

Q: Can I create indexes on table variables?

A: Yes, you can create indexes on table variables, but they aren’t as impactful as indexes on temporary tables due to the lack of statistics on table variables.

By understanding the nuances of both table variables and temporary tables, you can make informed decisions that will significantly improve the performance of your SQL Server queries. Ready to optimize your database? Explore advanced SQL Server training programs and resources to further enhance your skills and unlock the full potential of your database environment. Consider checking out resources on indexing strategies and query optimization techniques to further refine your database knowledge and build more efficient applications. ITPro Today also offers valuable insights into tempdb usage, which is crucial for understanding the impact of temporary tables.

Question & Answer :
I’m learning more details in table variable. It says that temp tables are always on disk, and table variables are in memory, that is to say, the performance of table variable is better than temp table because table variable uses less IO operations than temp table.

But sometimes, if there are too many records in a table variable that can not be contained in memory, the table variable will be put on disk like the temp table.

But I don’t know what the “too many records” is. 100,000 records? or 1000,000 records? How can I know if a table variable I’m using is in memory or is on disk? Is there any function or tool in SQL Server 2005 to measure the scale of the table variable or letting me know when the table variable is put on disk from memory?

Your question shows you have succumbed to some of the common misconceptions surrounding table variables and temporary tables.

I have written quite an extensive answer on the DBA site looking at the differences between the two object types. This also addresses your question about disk vs memory (I didn’t see any significant difference in behaviour between the two).

Regarding the question in the title though as to when to use a table variable vs a local temporary table you don’t always have a choice. In functions, for example, it is only possible to use a table variable and if you need to write to the table in a child scope then only a #temp table will do (table-valued parameters allow readonly access).

Where you do have a choice some suggestions are below (though the most reliable method is to simply test both with your specific workload).

  1. If you need an index that cannot be created on a table variable then you will of course need a #temporary table. The details of this are version dependant however. For SQL Server 2012 and below the only indexes that could be created on table variables were those implicitly created through a UNIQUE or PRIMARY KEY constraint. SQL Server 2014 introduced inline index syntax for a subset of the options available in CREATE INDEX. This has been extended since to allow filtered index conditions. Indexes with INCLUDE-d columns or columnstore indexes are still not possible to create on table variables however.
  2. If you will be repeatedly adding and deleting large numbers of rows from the table then use a #temporary table. That supports TRUNCATE (which is more efficient than DELETE for large tables) and additionally subsequent inserts following a TRUNCATE can have better performance than those following a DELETE as illustrated here.
  3. If you will be deleting or updating a large number of rows then the temp table may well perform much better than a table variable - if it is able to use rowset sharing (see “Effects of rowset sharing” below for an example).
  4. If the optimal plan using the table will vary dependent on data then use a #temporary table. That supports creation of statistics which allows the plan to be dynamically recompiled according to the data (though for cached temporary tables in stored procedures the recompilation behaviour needs to be understood separately).
  5. If the optimal plan for the query using the table is unlikely to ever change then you may consider a table variable to skip the overhead of statistics creation and recompiles (would possibly require hints to fix the plan you want).
  6. If the source for the data inserted to the table is from a potentially expensive SELECT statement then consider that using a table variable will block the possibility of this using a parallel plan.
  7. If you need the data in the table to survive a rollback of an outer user transaction then use a table variable. A possible use case for this might be logging the progress of different steps in a long SQL batch.
  8. When using a #temp table within a user transaction locks can be held longer than for table variables (potentially until the end of transaction vs end of statement dependent on the type of lock and isolation level) and also it can prevent truncation of the tempdb transaction log until the user transaction ends. So this might favour the use of table variables.
  9. Within stored routines, both table variables and temporary tables can be cached. The metadata maintenance for cached table variables is less than that for #temporary tables. Bob Ward points out in his tempdb presentation that this can cause additional contention on system tables under conditions of high concurrency. Additionally, when dealing with small quantities of data this can make a measurable difference to performance.

Effects of rowset sharing

DECLARE @T TABLE(id INT PRIMARY KEY, Flag BIT); CREATE TABLE #T (id INT PRIMARY KEY, Flag BIT); INSERT INTO @T output inserted.* into #T SELECT TOP 1000000 ROW_NUMBER() OVER (ORDER BY @@SPID), 0 FROM master..spt_values v1, master..spt_values v2 SET STATISTICS TIME ON /*CPU time = 7016 ms, elapsed time = 7860 ms.*/ UPDATE @T SET Flag=1; /*CPU time = 6234 ms, elapsed time = 7236 ms.*/ DELETE FROM @T /* CPU time = 828 ms, elapsed time = 1120 ms.*/ UPDATE #T SET Flag=1; /*CPU time = 672 ms, elapsed time = 980 ms.*/ DELETE FROM #T DROP TABLE #T