SQL Server:计算列是否存在性能成本?

15

如果我在表中包含计算列,是否会给它带来性能负担?

举个例子,如果我定义了如下表:

CREATE TABLE users(
    givenname …,
    familyname …,
    fullname AS givenname+' '+familyname
);

每次我从查询中SELECT,它是否会重新计算?

如果计算列是PERSISTED,这是否有帮助?

3个回答

10
如果在查询中引用了该列,则计算将在查询期间至少执行一次。这是避免使用 select * ... 的(又一个)好理由 - 如果您针对 users 表的查询没有引用 fullname 列,则不会执行任何计算。
如果计算列是 PERSISTED,显然不需要执行计算,但现在需要支付检索持久数据的一小部分存储和 I/O 成本。
简而言之,不要试图猜测这些事情。如果这是常见的计算,请为其创建计算列。稍后,一旦您有了 性能目标 并且可以 测量 您的性能,您可以评估它是否具有 有意义的 性能问题以及 persisted 折衷(计算与存储)是否对此产生影响。

此外,也许最好在从数据库检索数据后,在服务器端计算该列的计算。在C#/PHP /等中进行计算比在SQL中进行计算更好,并且可以节省一些存储以换取内存成本。 - Razvan Dumitru
关于存储,我通常认为在2018年,如果你担心存储问题,那就选择一个更大的盒子。相比性能,存储通常更加经济实惠。在这个例子中,假设结果不需要重新计算,如果你只需要“全名”这一列,那么持久化列在处理和I/O方面都会更加便宜。抱歉让你等了这么久才接受答案。 - Manngo

4

如果计算列是PERSISTED,选择数据时就不会有性能问题(但插入数据会有)。

是的,每次选择数据时都会重新计算。


3
我的测试表明,即使你保留了该列,每次选择时它们也会被重新计算。
以下是一些测试数据。
create table numm
(
id int,
 col_not_persist  as id+1,
col_persist as id+1 persisted
)

insert into numm
(id)
select number from Numbers--just numbers from 1 -1000000

现在当你查询
select * from numm

执行计划显示了两个标量运算符(尽管成本较低),如果您可以看到右上角的定义...您会发现它们每次被引用时都会被计算。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接