我正在学习表变量的更多细节。它说临时表总是在磁盘上,而表变量在内存中,也就是说,表变量的性能比临时表好,因为表变量比临时表使用更少的IO操作。

但是有时候,如果一个表变量中有太多记录不能包含在内存中,那么这个表变量就会像临时表一样被放到磁盘上。

但我不知道“太多记录”是什么意思。100000条记录吗?还是100万条记录?我如何知道我正在使用的表变量是在内存中还是在磁盘上?在SQL Server 2005中是否有任何函数或工具来测量表变量的规模,或者让我知道表变量何时从内存中放到磁盘上?


当前回答

我完全同意Abacus的观点(抱歉,我没有足够的分数来评论)。

另外,请记住,这并不一定取决于您有多少记录,而是取决于您的记录的大小。

例如,您是否考虑过每个记录有50个列的1,000条记录与每个记录只有5个列的100,000条记录之间的性能差异?

最后,可能您查询/存储的数据超过了您的需要?这里有一篇关于SQL优化策略的好文章。限制您提取的数据量,特别是如果您没有使用所有数据(一些SQL程序员确实很懒,即使他们只使用很小的子集,也会选择所有数据)。不要忘记SQL查询分析器也可能成为您最好的朋友。

其他回答

我完全同意Abacus的观点(抱歉,我没有足够的分数来评论)。

另外,请记住,这并不一定取决于您有多少记录,而是取决于您的记录的大小。

例如,您是否考虑过每个记录有50个列的1,000条记录与每个记录只有5个列的100,000条记录之间的性能差异?

最后,可能您查询/存储的数据超过了您的需要?这里有一篇关于SQL优化策略的好文章。限制您提取的数据量,特别是如果您没有使用所有数据(一些SQL程序员确实很懒,即使他们只使用很小的子集,也会选择所有数据)。不要忘记SQL查询分析器也可能成为您最好的朋友。

变量表仅对当前会话可用,例如,如果您需要EXEC当前存储过程中的另一个存储过程,则必须将表作为表值参数传递,当然这将影响性能,对于临时表,您可以仅通过传递临时表名来实现这一点

测试一个临时表:

打开管理工作室查询编辑器 创建临时表 打开另一个查询编辑器窗口 从这个表中选择“Available”

测试一个变量表:

打开管理工作室查询编辑器 创建一个变量表 打开另一个查询编辑器窗口 从这个表中选择“不可用”

我的另一个经验是:如果你的模式没有GRANT特权来创建表,那么就使用变量表。

写数据在表声明声明@tb和加入其他表后,我意识到响应时间相比临时表tempdb ..# TB要高得多。

当我用@tb连接它们时,返回结果的时间要长得多,不像#tm,返回几乎是瞬时的。

我使用10,000行连接和与其他5个表连接进行了测试

微软说

表变量没有分布统计信息,它们不会触发重新编译。因此,在许多情况下,优化器将在假定表变量没有行的基础上构建查询计划。出于这个原因,如果需要更大的行数(大于100),则应该谨慎使用表变量。在这种情况下,临时表可能是更好的解决方案。

如果数据量很小(数千字节),则使用表变量

对大量数据使用临时表

另一种考虑方法是:如果您认为可以从索引、自动统计数据或任何SQL优化器中受益,那么您的数据集对于表变量来说可能太大了。

在我的示例中,我只想将大约20行放入一种格式,并将它们作为一个组进行修改,然后使用它们来UPDATE / INSERT一个永久表。所以表变量是完美的。

但是我也运行SQL一次回填数千行,我可以肯定地说,临时表的性能比表变量好得多。

这与CTE的大小相似——如果CTE中的数据非常小,我发现CTE的性能与优化器提供的数据一样好,甚至更好,但如果它相当大,那么它会对您造成严重伤害。

我的理解主要基于http://www.developerfusion.com/article/84397/table-variables-v-temporary-tables-in-sql-server/,它有更多的细节。