Sql server 2005 存储过程中哪些变量最好
我经常使用数据导入或数据导出处理两个系统之间的一些接口。因此,我正在编写一些T-SQL过程。在这些过程中经常需要使用一些变量来保存一些值或单个记录 上次我设置了一些临时表,例如一个名为Sql server 2005 存储过程中哪些变量最好,sql-server-2005,sql-server-2008,Sql Server 2005,Sql Server 2008,我经常使用数据导入或数据导出处理两个系统之间的一些接口。因此,我正在编写一些T-SQL过程。在这些过程中经常需要使用一些变量来保存一些值或单个记录 上次我设置了一些临时表,例如一个名为#tmpGlobals,另一个名为#tmpOutput。名称并不重要,但我取消了声明一些@MainID int之类的内容 这是个好主意吗?这是性能问题吗?这实际上取决于数据量。如果您使用的记录少于100条,那么DECLARE@MainID或类似的记录可能会更好,因为它的数据量更小。但是,如果记录数超过100条,则绝
#tmpGlobals
,另一个名为#tmpOutput
。名称并不重要,但我取消了声明一些@MainID int
之类的内容
这是个好主意吗?这是性能问题吗?这实际上取决于数据量。如果您使用的记录少于100条,那么
DECLARE@MainID
或类似的记录可能会更好,因为它的数据量更小。但是,如果记录数超过100条,则绝对应该使用#tmpGlobals
或类似的方法,因为这样更适合SQL server上的内存管理
编辑:对于较小的集合使用
#tmpGlobals
并不是坏事,只是DECLARE@MainID
不会带来太多性能损失或收益。在大量记录上使用#tmpGlobals
而不是DECLARE@MainID
时,您将看到性能提高。通常,如果可能,您应该选择相反的方式。这取决于您是需要存储一组项还是只存储结果值
除表变量外,作用域变量相对便宜。适合非表的类型化变量的操作比将它们存储为表中的单行要快
表变量和临时表往往非常昂贵。它们可能需要tempdb中的空间,并且默认情况下不提供任何优化。此外,对于大型数据集,应避免使用表变量。处理大型集合时,如果愿意,可以在临时表上应用索引和定义主键,但不能对表变量执行此操作。最后,临时表需要在退出作用域之前进行清理 对于参数,表变量对于函数的返回集很有用。无法从函数返回临时表。根据手头的任务,使用函数可以更容易地封装工作的特定部分。您可能会发现某些存储过程所做的工作更适合于函数,尤其是在重用但不修改结果的情况下 最后,如果只需要在存储过程中间存储一次结果,就试试CTEs。这些通常会击败表变量和临时表,因为SQLServer可以更好地决定如何存储这些数据。此外,在语法方面,它可能会使您的声明更清晰 编辑:(关于临时表) 查询会话结束时,本地临时表将消失,这在将来可能是一个不确定的时间量。在连接关闭且没有其他用户使用该表之前,全局临时表不会消失,甚至可能更长。在这两种情况下,最好在过程退出时删除临时表(不再需要),以避免占用内存和其他资源
在许多情况下,CTE可以用来避免这种情况,因为它们仅位于声明它们的位置。一旦存储过程或其作用域的函数退出,它们就会自动标记为清除。正如Alexander所建议的,这取决于具体情况。我不会在沙子上画关于行数的硬线,因为它也可能取决于数据类型,因此也取决于每行的大小。在您的环境中,其中一个比另一个更有意义,这取决于几个因素,而不仅仅是数据的大小,包括访问模式、性能对重新编译的敏感性、您的硬件等 有一种常见的误解是@table变量仅在内存中,不产生I/O,不使用tempdb等。在某些孤立的情况下,有些是正确的,但这不是您可以或应该依赖的 @table变量的一些其他限制可能会阻止您使用它们,即使是对于小数据集:
- 无法索引(创建时主键/唯一约束声明除外)
- 不维护统计数据(与#临时表不同)
- 无法改变
- 无法在SQL Server 2005中用作插入执行目标(此限制在2008年取消)
- 无法作为选择目标使用
- 不能截断
- 无法在定义中使用别名类型
- 没有平行性
- 嵌套进程不可见(不同于#临时表)