在SQL Server 2005中,有两种方法可以创建临时表:
declare @tmp table (Col1 int, Col2 int);
or
create table #tmp (Col1 int, Col2 int);
这两者之间有什么区别?关于@tmp是否仍然使用tempdb,或者是否所有事情都发生在内存中,我读过相互矛盾的意见。
在哪些情况下,一个会优于另一个?
在SQL Server 2005中,有两种方法可以创建临时表:
declare @tmp table (Col1 int, Col2 int);
or
create table #tmp (Col1 int, Col2 int);
这两者之间有什么区别?关于@tmp是否仍然使用tempdb,或者是否所有事情都发生在内存中,我读过相互矛盾的意见。
在哪些情况下,一个会优于另一个?
当前回答
令我惊讶的是,没有人提到这两者之间的关键区别是临时表支持并行插入,而表变量不支持。您应该能够从执行计划中看出不同之处。下面是9频道和MSDN doc上的SQL workshop的视频。
这也解释了为什么应该对较小的表使用表变量,否则应该使用临时表,正如SQLMenace前面回答的那样。
其他回答
还要考虑到,您通常可以用派生表来替换这两个表,这也可能更快。但是,与所有性能调优一样,只有针对实际数据的实际测试才能告诉您特定查询的最佳方法。
临时表(#tmp)和表变量(@tmp)之间有一些区别,尽管使用tempdb不是其中之一,如下面MSDN链接中所述。
根据经验,对于中小数据量和简单的使用场景,应该使用表变量。(这是一个过于宽泛的指导方针,当然有很多例外-请参阅下面和下面的文章。)
在两者之间进行选择时需要考虑以下几点:
Temporary Tables are real tables so you can do things like CREATE INDEXes, etc. If you have large amounts of data for which accessing by index will be faster then temporary tables are a good option. Table variables can have indexes by using PRIMARY KEY or UNIQUE constraints. (If you want a non-unique index just include the primary key column as the last column in the unique constraint. If you don't have a unique column, you can use an identity column.) SQL 2014 has non-unique indexes too. Table variables don't participate in transactions and SELECTs are implicitly with NOLOCK. The transaction behaviour can be very helpful, for instance if you want to ROLLBACK midway through a procedure then table variables populated during that transaction will still be populated! Temp tables might result in stored procedures being recompiled, perhaps often. Table variables will not. You can create a temp table using SELECT INTO, which can be quicker to write (good for ad-hoc querying) and may allow you to deal with changing datatypes over time, since you don't need to define your temp table structure upfront. You can pass table variables back from functions, enabling you to encapsulate and reuse logic much easier (eg make a function to split a string into a table of values on some arbitrary delimiter). Using Table Variables within user-defined functions enables those functions to be used more widely (see CREATE FUNCTION documentation for details). If you're writing a function you should use table variables over temp tables unless there's a compelling need otherwise. Both table variables and temp tables are stored in tempdb. But table variables (since 2005) default to the collation of the current database versus temp tables which take the default collation of tempdb (ref). This means you should be aware of collation issues if using temp tables and your db collation is different to tempdb's, causing problems if you want to compare data in the temp table with data in your database. Global Temp Tables (##tmp) are another type of temp table available to all sessions and users.
进一步阅读:
Martin Smith在dba.stackexchange.com上给出了很好的回答 MSDN常见问题解答:https://support.microsoft.com/en-gb/kb/305977 MDSN博客文章:https://learn.microsoft.com/archive/blogs/sqlserverstorageengine/tempdb-table-variable-vs-local-temporary-table 文章:https://searchsqlserver.techtarget.com/tip/Temporary-tables-in-SQL-Server-vs-table-variables 临时表和临时变量的意外行为和性能影响:Paul White在SQLblog.com上的文章
在哪些情况下,一个会优于另一个?
对于较小的表(小于1000行),使用临时变量,否则使用临时表。
对于所有相信临时变量只存在于内存中的人
首先,表变量不一定存在于内存中。在内存压力下,属于表变量的页可以被推到tempdb。
在这里阅读文章:TempDB::表变量vs本地临时表
@wcm -实际上nit选择表变量不只是Ram -它可以部分存储在磁盘上。
临时表可以有索引,而表变量只能有主索引。如果速度是一个问题,表变量可以更快,但显然如果有很多记录,或者需要搜索聚集索引的临时表,那么临时表将更好。
好的背景文章