我正在学习表变量的更多细节。它说临时表总是在磁盘上,表变量在内存中,也就是说,表变量的性能比临时表好,因为表变量比临时表使用更少的输入输出操作。
但有时,如果一个表变量中有太多无法包含在内存中的记录,该表变量将像临时表一样放在磁盘上。
但我不知道“记录太多”是什么。100000条记录?还是1000000条记录?如何知道我使用的表变量是在内存中还是在磁盘上?SQL Server 2005中是否有任何函数或工具可以测量表变量的规模,或者让我知道表变量何时从内存中放入磁盘?
微软在这里说
表变量没有分布统计信息,它们不会触发重新编译。因此,在许多情况下,优化器将在假设表变量没有行的基础上构建查询计划。出于这个原因,如果您希望有更多的行(大于100),那么应该谨慎使用表变量。在这种情况下,临时表可能是更好的解决方案。
如果数据量非常小(数千字节),请使用表变量
对大量数据使用临时表
另一种思考方法:如果您认为您可能会从索引、自动统计或任何SQL优化器的优点中受益,那么您的数据集对于表变量来说可能太大了。
在我的示例中,我只想将大约20行放入一种格式并将它们作为一个组进行修改,然后使用它们来UPDATE/INSERT永久表。所以表变量是完美的。
但我也在运行SQL,一次回填数千行,我可以肯定地说,临时表的性能要比表变量好得多。
这与CTE因相似大小的原因而受到关注的方式没有什么不同-如果CTE中的数据非常小,我发现CTE的性能与优化器的性能一样好或更好,但如果它非常大,则会对您造成很大的伤害。
我的理解主要基于http://www.developerfusion.com/article/84397/table-variables-v-temporary-tables-in-sql-server/,它有更多的细节。
您的问题表明您已经屈服于围绕表变量和临时表的一些常见误解。
我在DBA站点上写了一个相当广泛的答案,讨论了这两种对象类型之间的差异。这也解决了您关于磁盘与内存的问题(我看不出两者在行为上有任何显著差异)。
关于标题中关于何时使用表变量和本地临时表的问题,您并不总是有选择的余地。例如,在函数中,只能使用表变量,如果需要在子作用域中写入表,则只能使用临时表(表值参数允许只读访问)。
下面是一些建议(尽管最可靠的方法是简单地用您的特定工作负载测试两者)。
>
如果要从表中重复添加和删除大量行,请使用临时表。支持截短(对于大型表,这比删除更有效)以及在截短之后的后续插入可以比删除之后的插入具有更好的性能,如图所示。
行集共享的影响
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
问题内容: 我一直在研究代码中Unicode’N’常量的使用,例如: 在阅读了什么时候使用它的内容之后,我仍然不清楚应该在什么情况下使用它,以及在什么情况下不应该使用它。 当数据类型或参数需要unicode数据类型时(如上述示例),它是否像使用它一样简单,还是比它更复杂? 以下Microsoft网站提供了解释,但对于使用http://msdn.microsoft.com/zh- cn/librar
问题内容: 我知道他们两个都禁用了Nagle的算法。 我什么时候应该/不应该使用它们中的每一个? 问题答案: 首先,不是所有人都禁用Nagle的算法。 Nagle的算法用于减少有线中更多的小型网络数据包。该算法是:如果数据小于限制(通常是MSS),请等待直到收到先前发送的数据包的ACK,同时累积用户的数据。然后发送累积的数据。 这将对telnet等应用程序有所帮助。但是,在发送流数据时,等待A
问题内容: 在该类中,有两个字符串,和。 有什么不同?我什么时候应该使用另一个? 问题答案: 如果你的意思是和则: 用于在文件路径列表中分隔各个文件路径。考虑在上的环境变量。您使用a分隔文件路径,因此在上将是;。 是或用于拆分到特定文件的路径。例如在上,或
问题内容: 我是OOP范式的新手,所以可能对此问题有一个简单的解释… 您是否总是需要在类中声明公共对象范围的变量?例如: 在此代码中,即使是唯一声明的变量,也一样可访问和可用-似乎就像我将其声明为public一样。 如果未声明的类变量始终可以这样访问,那么将它们全部预先声明的意义何在? 问题答案: 该变量不是未初始化的,只是未声明的。 在类定义中声明变量是提高可读性的一种方式。另外,您可以设置可访
美元符号($)是命名变量的有效字符,例如,但是当我们讨论命名约定时,我应该在什么时候使用这个符号呢? 例如,下划线最常用来分隔单词,因为不允许有空格。
问题内容: 这不是一个关于之间的差异问题 和 。 我知道对象不能接受键或值条目的值,它是同步集合,并且使用的内存比少。 我想知道哪种情况更适合使用a 而不是a 。 问题答案: 这不是一个关于之间的差异问题和 好吧,真的。。。 我想知道哪种情况更适合使用a 而不是a 。 正是在您 想要 两者之间的差异时: 当您想在Java 1.1上运行时 当您希望每个操作都进行同步时(只要您从不迭代它,就可以得到一