Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2005 存储过程中哪些变量最好_Sql Server 2005_Sql Server 2008 - Fatal编程技术网

Sql server 2005 存储过程中哪些变量最好

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条,则绝

我经常使用数据导入或数据导出处理两个系统之间的一些接口。因此,我正在编写一些T-SQL过程。在这些过程中经常需要使用一些变量来保存一些值或单个记录

上次我设置了一些临时表,例如一个名为
#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年取消)
  • 无法作为选择目标使用
  • 不能截断
  • 无法在定义中使用别名类型
  • 没有平行性
  • 嵌套进程不可见(不同于#临时表)

“最后,临时表在退出作用域之前需要清理”:它们不会自行“消失”吗?它们会在会话结束后过期,但如果您在Management Studio中进行测试,最好在代码中处理完临时表后尽快习惯放置DROP TABLE#tblTemp。不管怎样,把它们清理干净是个好习惯:)我同意把它们清理干净是个好习惯。尽管DROP TABLE#foo和现有范围都不会立即销毁#temp表;有一个后台进程会出现并删除任何标记为要销毁的表。实际上,有perfmon计数器可以让您查看“表创建/销毁”的速率。哦,Aaron的帖子暗示,如果storeproc使用了许多“易受诱惑的内容”,并且经常被执行,那么在很短的时间内,有数百个“易受诱惑的内容”将被此后台进程销毁。这有点像性能杀手吗?我们是否应该像这样定义更具全球性的“诱惑物”,以避免这种副作用?如果存在,必须在进程开始时截断它…使用全局可诱惑(##可诱惑)更糟糕。有两种方法可以获得数百个诱人的东西:1。在一个存储过程中生成数百个临时表(不太可能);2.调用只创建一个临时表的存储过程(可能)。如果您使用全局临时表,则必须防止多个连接竞争访问和访问权限