首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TSQL while循环与合并

TSQL while循环与合并
EN

Stack Overflow用户
提问于 2013-05-15 04:54:44
回答 1查看 2.2K关注 0票数 1

一般来说,我对SQL和数据库都是很陌生的。我正在使用SQL Server 2008 Mgmt Studio。

我读到过使用基于集合的操作比使用RBAR更好(这是今天才学到的!)

稍后,我将向您展示两个等价的(我认为)查询,并尝试查看哪一个更有效。

第一次尝试:

代码语言:javascript
复制
DECLARE @persID int
DECLARE @mag    float
DECLARE @temp TABLE (pID int PRIMARY KEY)

INSERT INTO @temp
SELECT persID FROM Person

WHILE (SELECT COUNT(pID) FROM @temp) > 0
BEGIN
   SELECT TOP 1 @persID = pID FROM @temp    
   SELECT @mag = SQRT(SUM(value*value)) FROM PersonWord 
      WHERE PersonWord.persID = @persID

   UPDATE Person
   SET magnitude = @mag
      WHERE persID  = @persID
   DELETE @temp WHERE pID = @persID
END

第二次尝试:

代码语言:javascript
复制
DECLARE @temp TABLE (pID int PRIMARY KEY, mag float)

INSERT INTO @temp
   SELECT persID, SQRT(SUM(value*value)) FROM PersonWord
      GROUP BY persID

MERGE INTO Person AS p
USING @temp AS t
   ON p.persID = t.pID
WHEN MATCHED
THEN UPDATE
   SET magnitude = t.mag

这些将保存为存储过程和运行时的估计执行计划:

代码语言:javascript
复制
exec FirstAttempt
exec SecondAttempt

显示32%的批次用于FirstAttempt,68%用于SecondAttempt

PersonWord表包含约4100万records...the Person表包含约170,000

任何想法/建议都是非常受欢迎的。感谢你抽出时间,我知道新手问题有多令人沮丧(在雅虎上做数学帮助)。

编辑::

在PersonWord上运行那些拥有大约130万条记录和大约3000条记录的人...具有merge的版本花了大约1.3秒来执行。带有while循环的版本只有6分钟,并且只完成了大约15%的作业。

对于这类事情,使用Set-based而不是RBAR!

EN

回答 1

Stack Overflow用户

发布于 2013-05-15 05:30:02

永远不要使用表变量来表示该数量的记录。它们是针对小数据集的。请改用临时表,并为其编制索引。此外,我个人会寻找一种方法来限制您正在更新的记录的数量。我不知道你为什么要使用合并,因为这只是一个简单的更新。下面的代码应该可以工作。

代码语言:javascript
复制
Update P
set   SET magnitude = t.mag
from Person AS p
join  #temp AS t
   ON p.persID = t.pID
WHERE magnitude <> t.mag

根据您执行此操作的频率,我将尝试存储此计算,以便每条记录只需要执行一次计算(并使用rtigger在值发生变化时保持更新):SQRT(SUM(value*value))

顺便说一句,在任何数学计算中使用浮点数都是一种糟糕的做法,因为它并不精确,因此会引入舍入误差。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16552671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档