SQL更新中WHERE子句的速度影响

SQL更新中WHERE子句的速度影响,sql,performance,db2,where-clause,Sql,Performance,Db2,Where Clause,我在DB2(IBMSystemi)表上有一个非常简单的SQLUpdate命令,该表包含大约3000万条记录 UPDATE tablename SET field = 0 where field > 0 现在,考虑到字段永远不能小于0并且不能为null,那么“where”子句不是不必要的吗WHERE子句是否影响此过程的持续时间 据我所知,这是不必要的,而且会影响速度,因为数据库必须评估每个记录。我正试图找出这一点,因为我自己无法运行SQLs,我们的分包商说它没有影响;我们没有知识来证明/

我在DB2(IBMSystemi)表上有一个非常简单的SQLUpdate命令,该表包含大约3000万条记录

UPDATE tablename SET field = 0 where field > 0 
现在,考虑到字段永远不能小于0并且不能为null,那么“where”子句不是不必要的吗WHERE子句是否影响此过程的持续时间


据我所知,这是不必要的,而且会影响速度,因为数据库必须评估每个记录。我正试图找出这一点,因为我自己无法运行SQLs,我们的分包商说它没有影响;我们没有知识来证明/证伪这一点。

结论:如果字段列中没有0,则where在运行时只有很小的差异。 如果有几个0's a很快就会变快 如果字段列中可能出现0,则where子句很快会赢得speed和imo的支持

我制作了一个包含4.967.877行的db表

我用0填充了一半行,用1填充了另一半行

UPDATE HugeDummyTable
SET field = 0
WHERE HugeDummyTableID < 2483938

UPDATE HugeDummyTable
SET field = 1
WHERE HugeDummyTableID >= 2483938
给出结果:

SQL Server Execution Times:
CPU time = 1829 ms,  elapsed time = 1842 ms.
(2483940 row(s) affected)
使用相同的第一个查询重置表。 在不使用where的情况下执行查询

SET STATISTICS TIME ON
UPDATE HugeDummyTable SET field = 0
给出以下结果:

SQL Server Execution Times:
CPU time = 2765 ms,  elapsed time = 2791 ms.
(4967877 row(s) affected)
所以我认为where使得查询速度更快

评论后编辑:用随机数填充列“字段” 为了确保我将使用相同的表进行2次尝试,我做了一个备份

Update HugeDummyTable
SET field = ABS(Checksum(NewId()) % 100000)
看看我有多少0:

SELECT COUNT(field)
FROM HugeDummyTable
WHERE field = 0 
"45"
使用以下位置运行查询:

SET STATISTICS TIME ON
UPDATE HugeDummyTable SET field = 0 where field > 0 
SET STATISTICS TIME ON
UPDATE HugeDummyTable SET field = 0 where field > 0

SQL Server Execution Times:
CPU time = 3313 ms,  elapsed time = 3325 ms.

(4967829 row(s) affected)
已还原的表,重新运行,不带以下位置:

SET STATISTICS TIME ON
UPDATE HugeDummyTable SET field = 0

SQL Server Execution Times:
CPU time = 3094 ms,  elapsed time = 3121 ms.

(4967877 row(s) affected)
差别较小,但仍然存在。where似乎缩短了一点时间,即使只有45条记录的差异

编辑2:测试时不使用0

这次字段列中没有0 没有哪里

SQL Server Execution Times:
CPU time = 3109 ms,  elapsed time = 3238 ms.
在哪里

SQL Server Execution Times:
CPU time = 3172 ms,  elapsed time = 3337 ms.    

如果
字段
的列类型可以为空,则会产生影响。NULL将在
字段>0
中计算为false。如果字段仅在您获得一些数据后才设置为值,则可以说该字段表示今天发送的电子邮件,原始DBA允许
字段
为空,即
未知
。如果你运行这个

UPDATE tablename SET field = 0;
每个人都会被重置,而你就失去了发现有多少人从未发送过电子邮件的能力

select count(*) from tablename where field = NULL

因此,根据您的模式和语义,这可能意味着很多。注意,这只是一个例子,我并不是说这是一个很好的设计,也不是一个很好的NULL用法。

立即更新30mln记录?列
字段
是否索引?如果是,可能根本没有差别,如果不是,可能差别不大。是的,立即更新3000万条记录。不,据我所知,该字段没有索引。ps:我刚才看到有一个专门的子“stackexchange”,用于“数据库管理员”。有什么方法可以将我的主题移动到那里吗?它将排除列为空的行。如果该列上有索引,这实际上可能会使它更快。如果它不能为空,那么我同意它不会有什么不同。如果删除它,数据库将需要更新所有行,如果保留它,它还需要更新所有行。主要的性能“问题”通常是实际的更新,没有找到行。不过,请解释为什么会出现这种情况?在运行基准测试之前,您应该使用
1s
0s
随机化记录的顺序。@jordums如果您使用where子句,您将更新一半的行数。@SeanPearce True,所以事实上,这个测试并不是OP想要的。因为OP没有“真实”条件。