我经常使用数据导入或数据导出处理两个系统之间的某些接口。因此我正在编写一些T-SQL过程。通常需要在这些过程中使用一些变量来保存一些值或单个记录。
我最后一次设置一些临时表,例如一个名为#tmpGlobals
,另一个名为#tmpOutput
。名字并不重要,但我没有使用声明一些@MainID int
或类似的名称。
这是个好主意吗?这是性能问题吗?
答案 0 :(得分:1)
亚历山大建议,这实际上取决于。我不会在沙子中绘制关于行数的强硬线,因为它还可以取决于数据类型,因此也取决于每行的大小。除了数据的大小,包括访问模式,性能对重新编译的敏感性,硬件等等,在您的环境中哪一个比另一个更有意义可以取决于几个因素。
有一种常见的误解,即@table变量只存在于内存中,不会产生I / O,不会使用tempdb等。虽然在某些孤立的情况下,其中一些是真的,但这不是你可以或应该做的事情。依靠。
@table变量的一些其他限制可能会阻止您使用它们,即使对于小数据集也是如此:
答案 1 :(得分:0)
这实际上取决于数据量。如果您使用的是100条以下的记录,那么DECLARE @MainID
之类的内容可能会更好,因为它的数据量较少。但是,任何超过100条记录的内容都应该使用#tmpGlobals
或类似内容,因为它更适合SQL服务器上的内存管理。
编辑:对于较小的集合使用#tmpGlobals
并非错误,只是DECLARE @MainID
的性能损失或增益不大。在大量记录上使用#tmpGlobals
而不是DECLARE @MainID
时,您会看到性能提升。
答案 2 :(得分:0)
一般情况下,如果可能,您应该选择反向。这取决于您是需要存储一组项目还是仅存储结果值。
除了表变量之外,范围变量相对便宜。适合不是表的类型变量的事情比将它们作为单行存储在表中运行得更快。
表变量和临时表往往非常昂贵。它们可能需要tempdb中的空间,并且默认情况下也不提供优化。此外,对于大型数据集应避免使用表变量。处理大型集时,您可以根据需要应用索引并在临时表上定义主键,但不能对表变量执行此操作。最后,临时表在退出范围之前需要清理。
对于参数,表变量对函数的返回集很有用。无法从函数返回临时表。根据手头的任务,使用函数可以更容易地封装特定的工作部分。您可能会发现某些存储过程正在执行更适合函数的工作,尤其是在重用但不修改结果时。
最后,如果您只需要在存储过程工作中间一次性存储结果,请尝试CTE。这些通常会超出表变量和临时表,因为SQL服务器可以更好地决定如何为您存储这些数据。此外,作为语法问题,它可能使您的声明更清晰。
Using Common-Table Expressions @ MSDN
编辑:(关于临时表格)
当查询会话结束时,本地临时表会消失,这可能是将来不确定的时间量。在关闭连接并且没有其他用户使用该表之前,全局临时表不会消失,这可能更长。在任何一种情况下,最好在退出过程时删除临时表(不再需要)以避免占用内存和其他资源。
在许多情况下,可以使用CTE来避免这种情况,因为它们只是声明它们的位置的本地。一旦存储过程或函数范围退出,它们就会自动标记为清理。