【发布时间】:2013-05-09 07:03:50
【问题描述】:
总的来说,我对 SQL 和数据库还很陌生。我正在使用 SQL Server 2008 Mgmt Studio。
我读到使用基于集合的操作比 RBAR 更好(今天才知道!)。
很快,我将向您展示两个等效的(我认为)查询,我想看看哪个更 高效。
第一次尝试:
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
第二次尝试:
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
这些在运行时保存为存储过程和估计的执行计划:
exec FirstAttempt
exec SecondAttempt
第一次尝试显示 32% 的批次,第二次尝试显示 68% 的批次
PersonWord 表包含大约 4100 万条记录...Person 表包含
大约 170,000
欢迎提出任何想法/建议。感谢您抽出宝贵的时间,我知道新手问题是多么令人沮丧(用于在 Yahoo 上做数学帮助)。
编辑::
在拥有约 130 万条记录的 PersonWord 和拥有约 3000 条记录的 PersonWord 上运行这些...合并的版本大约需要 1.3 秒才能执行。带有 while 循环的版本用时 6 分钟,只完成了约 15% 的工作。
对于这种事情,基于集合而不是 RBAR!
【问题讨论】:
-
您已经看到了预估的执行计划,可以得到实际的执行计划。您有适合 StackOverflow 的问题吗?
-
在 Sql Server Mgt Studio 中,右键单击查询并选择
include client statistics,然后将每个查询运行六次左右。您将在输出中获得一个带有时间信息的额外选项卡。 “批次百分比”对我来说不是一个有用的指标。 -
@HABO 是的,对于那些了解 sql 来龙去脉的人来说,合并是否比 while 循环更好?我已经在这里待了 2 天,试图找到答案却得到了相互矛盾的结果
-
@DanPichelman 感谢 Dan,现在在大大减少的数据集(分别为 1 百万和 3,000)上运行它
-
1) 确保您在 Person.persId 上有一个索引 - 索引是加快数据库速度的第一方法; 2)在这种情况下,您不需要“合并”,因为您只做一件事(更新会做同样的事情); 3)如果您的@temp 表有很多记录,请使用#temp 表而不是表变量(当有很多记录时,临时表要快得多)-您还可以向#temp 表添加索引; 4)你自己做研究很好,但如果你发现基于集合的方法最终变慢了,那么你做错了什么;)
标签: sql-server tsql merge while-loop