代码之家  ›  专栏  ›  技术社区  ›  Ice

存储过程中哪些变量最好

  •  0
  • Ice  · 技术社区  · 15 年前

    上次我设置了一些临时表,例如带有名称的临时表 #tmpGlobals 还有一个叫 #tmpOutput . 名字不重要,但我取消了声明一些 @MainID int

    这是个好主意吗?这是性能问题吗?

    3 回复  |  直到 8 年前
        1
  •  1
  •   Aaron Bertrand    15 年前

    正如亚历山大所说,这要看情况而定。我不会在沙子上画关于行数的硬线,因为它也可能取决于数据类型,因此也取决于每行的大小。在您的环境中,其中一个比另一个更有意义,这取决于几个因素,而不仅仅是数据的大小,包括访问模式、性能对重新编译的敏感性、您的硬件等。

    有一种常见的误解是@table变量仅在内存中,不产生I/O,不使用tempdb等。在某些孤立的情况下,有些是正确的,但这不是您可以或应该依赖的。

    @table变量的一些其他限制可能会阻止您使用它们,即使是对于小数据集:

    • 无法索引(创建时主键/唯一约束声明除外)
    • 不维护统计数据(与#临时表不同)
    • 无法改变
    • 无法在SQL Server 2005中用作插入执行目标(此限制在2008年取消)
    • 无法作为选择目标使用
    • 不能截断
    • 无法在定义中使用别名类型
    • 嵌套进程不可见(不同于#临时表)
        2
  •  0
  •   Alexander Kahoun    15 年前

    这实际上取决于数据量。如果您使用的记录少于100条,那么 DECLARE @MainID 或者类似的方法可能更好,因为它的数据量更小。任何超过100条的记录,你都应该使用 #tmpGlobals 或者类似,因为它更适合SQL server上的内存管理。

    编辑:不是 坏的 使用 #tmpGlobals 对于较小的组,性能损失或增益不大 声明@MainID #tmpGlobals 声明@MainID

        3
  •  0
  •   meklarian    15 年前

    一般来说,如果可能的话,你应该选择相反的。这取决于您是需要存储一组项还是只存储结果值。

    对于参数,表变量对于函数的返回集很有用。无法从函数返回临时表。根据手头的任务,使用函数可以更容易地封装工作的特定部分。您可能会发现某些存储过程所做的工作更适合于函数,尤其是在重用但不修改结果的情况下。

    最后,如果只需要在存储过程工作的中间存储一次结果,请尝试CTEs。这些通常会击败表变量和临时表,因为SQLServer可以更好地决定如何存储这些数据。此外,在语法方面,它可能会使您的声明更清晰。

    Using Common-Table Expressions @ MSDN

    编辑:(关于临时表)

    查询会话结束时,本地临时表将消失,这在将来可能是一个不确定的时间量。在连接关闭且没有其他用户使用该表之前,全局临时表不会消失,甚至可能更长。在这两种情况下,最好在过程退出时删除临时表(不再需要),以避免占用内存和其他资源。