Computed Column(计算列)是自SQL Server 2005开始就有的特性。计算列的定义是一个表达式。表达式可以是非计算列,常量,函数间的组合。但是不可以是子查询。

计算列数据固化

默认情况下计算列的数据是存储在磁盘上,仅当计算列被查询引用是才进行实时计算。只在计算列在定义是添加了PERSISTED关键词是才将数据固化。

计算列上创建索引或者作为分区函数的引用列

计算列上是运行创建索引和作为分区函数的引用列。但是必须指定PERSISTED关键词。

用法其实很简单。那么这里有些问题。使用计算列的代价到底有多大?

INSERT发生时使用计算列和非计算列的性能区别

这里做一个测试。首先创建好两张表

IF EXISTS(SELECT * FROM sys.tables WHERE name = 'computed_column_test_computed')
BEGIN
DROP TABLE dbo.computed_column_test_computed
END IF EXISTS(SELECT * FROM sys.tables WHERE name = 'computed_column_test_noncomputed')
BEGIN
DROP TABLE dbo.computed_column_test_noncomputed
END CREATE TABLE dbo.computed_column_test_computed
(
dttm DATETIME,
dttm_year AS YEAR(dttm) PERSISTED,
dttm_month AS MONTH(dttm) PERSISTED,
dttm_nextday AS DATEADD(DAY,1,dttm) PERSISTED,
dttm_previousday AS DATEADD(DAY,-1,dttm) PERSISTED,
dttm_week AS DATEPART(ww,dttm),
dttm_monthname AS CASE DATEPART(mm, dttm)
WHEN 1 THEN 'January'
WHEN 2 THEN 'February'
WHEN 3 THEN 'March'
WHEN 4 THEN 'April'
WHEN 5 THEN 'May'
WHEN 6 THEN 'June'
WHEN 7 THEN 'July'
WHEN 8 THEN 'August'
WHEN 9 THEN 'September'
WHEN 10 THEN 'October'
WHEN 11 THEN 'November'
WHEN 12 THEN 'December'
END PERSISTED,
dttm_quarter AS DATEPART(qq,dttm) PERSISTED
) CREATE TABLE dbo.computed_column_test_noncomputed
(
dttm DATETIME,
dttm_year SMALLINT,
dttm_month SMALLINT,
dttm_nextday DATETIME,
dttm_previousday DATETIME,
dttm_week INT,
dttm_monthname VARCHAR(30),
dttm_quarter VARCHAR(30)
)

然后开启IO和TIME的统计信息开关,然后分别对两张表进行数据插入。

SET STATISTICS TIME ON
SET STATISTICS IO ON INSERT dbo.computed_column_test_computed(
dttm
)
SELECT DATEADD(SECOND, Num, GETDATE())
FROM dbo.Numbers
WHERE Num <= 1000000 INSERT dbo.computed_column_test_noncomputed(dttm ,
dttm_year ,
dttm_month ,
dttm_nextday ,
dttm_previousday ,
dttm_week ,
dttm_monthname ,
dttm_quarter)
SELECT GETDATE(),
YEAR(GETDATE()) PERSISTED,
MONTH(GETDATE()) PERSISTED,
DATEADD(DAY,1,GETDATE()) ,
DATEADD(DAY,-1,GETDATE()),
DATEPART(ww,GETDATE()),
CASE DATEPART(mm, GETDATE())
WHEN 1 THEN 'January'
WHEN 2 THEN 'February'
WHEN 3 THEN 'March'
WHEN 4 THEN 'April'
WHEN 5 THEN 'May'
WHEN 6 THEN 'June'
WHEN 7 THEN 'July'
WHEN 8 THEN 'August'
WHEN 9 THEN 'September'
WHEN 10 THEN 'October'
WHEN 11 THEN 'November'
WHEN 12 THEN 'December'
END,
DATEPART(qq,GETDATE())
FROM dbo.Numbers
WHERE Num <= 1000000

我的例子里面分别进行10万行、30万行、50万行和100万行数据的插入测试。一共有7个计算列。每个例子测试两次。

 SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Table 'computed_column_test_computed'. Scan count 0, logical reads 100840, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 164, physical reads 2, read-ahead reads 162, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 515 ms, elapsed time = 1564 ms. (100000 row(s) affected) SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 1327 ms.
Table 'computed_column_test_noncomputed'. Scan count 0, logical reads 100833, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 164, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 265 ms, elapsed time = 759 ms. (100000 row(s) affected) SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 5 ms. SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms. SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Table 'computed_column_test_computed'. Scan count 0, logical reads 100840, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 164, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 391 ms, elapsed time = 411 ms. (100000 row(s) affected)
Table 'computed_column_test_noncomputed'. Scan count 0, logical reads 100833, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 164, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 234 ms, elapsed time = 273 ms. (100000 row(s) affected) SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 6 ms.
Table 'computed_column_test_computed'. Scan count 0, logical reads 302521, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 487, physical reads 1, read-ahead reads 330, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 1250 ms, elapsed time = 1986 ms. (300000 row(s) affected)
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 74 ms.
Table 'computed_column_test_noncomputed'. Scan count 0, logical reads 302499, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 487, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 813 ms, elapsed time = 966 ms. (300000 row(s) affected) SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 14 ms.
Table 'computed_column_test_computed'. Scan count 0, logical reads 302521, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 487, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 1156 ms, elapsed time = 1709 ms. (300000 row(s) affected)
Table 'computed_column_test_noncomputed'. Scan count 0, logical reads 302499, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 487, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 734 ms, elapsed time = 3089 ms. (300000 row(s) affected) SQL Server parse and compile time:
CPU time = 8 ms, elapsed time = 8 ms.
Table 'computed_column_test_computed'. Scan count 0, logical reads 504201, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 809, physical reads 0, read-ahead reads 315, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 2031 ms, elapsed time = 2080 ms. (500000 row(s) affected)
Table 'computed_column_test_noncomputed'. Scan count 0, logical reads 504166, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 809, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 1297 ms, elapsed time = 2915 ms. (500000 row(s) affected) SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 4 ms.
Table 'computed_column_test_computed'. Scan count 0, logical reads 504201, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 809, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 1984 ms, elapsed time = 3540 ms. (500000 row(s) affected)
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 2 ms.
Table 'computed_column_test_noncomputed'. Scan count 0, logical reads 504166, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 809, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 1266 ms, elapsed time = 1341 ms. (500000 row(s) affected) SQL Server parse and compile time:
CPU time = 13 ms, elapsed time = 13 ms.
Table 'computed_column_test_computed'. Scan count 0, logical reads 1008359, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 1615, physical reads 0, read-ahead reads 791, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 4500 ms, elapsed time = 9110 ms. (1000000 row(s) affected)
Table 'computed_column_test_noncomputed'. Scan count 0, logical reads 1008333, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 1615, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 2531 ms, elapsed time = 3903 ms. (1000000 row(s) affected) SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 3 ms.
Table 'computed_column_test_computed'. Scan count 0, logical reads 1008359, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 1615, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 3797 ms, elapsed time = 6559 ms. (1000000 row(s) affected)
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 3 ms.
Table 'computed_column_test_noncomputed'. Scan count 0, logical reads 1008333, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 1615, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 2422 ms, elapsed time = 3895 ms. (1000000 row(s) affected)

可以看到确实使用computed column会对性能有一定的影响。当计算列数量越多的情况下性能的影响越大。但是当计算列数量很少的情况下,影响或者说差别其实很小很小。以我做的实验为例,讲计算列数量减少到只有3个,数据量依旧停留在100万行的情况,两者的性能差异其实已经很小了。

SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 4 ms. SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms. SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Table 'computed_column_test_computed'. Scan count 0, logical reads 1005813, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 1615, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 3203 ms, elapsed time = 5058 ms. (1000000 row(s) affected)
Table 'computed_column_test_noncomputed'. Scan count 0, logical reads 1005319, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 1615, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 2281 ms, elapsed time = 4747 ms. (1000000 row(s) affected) SQL Server parse and compile time:
CPU time = 16 ms, elapsed time = 28 ms.
Table 'computed_column_test_computed'. Scan count 0, logical reads 1005813, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 1615, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 2984 ms, elapsed time = 3512 ms. (1000000 row(s) affected)
Table 'computed_column_test_noncomputed'. Scan count 0, logical reads 1005319, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Numbers'. Scan count 1, logical reads 1615, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. SQL Server Execution Times:
CPU time = 2672 ms, elapsed time = 2859 ms. (1000000 row(s) affected)

那么总结下,计算列的使用原则我认为是在表中计算列的数量本身不多,而且一次性数据行插入量不大,计算逻辑固定,计算复杂度大的情况下,推荐使用计算列。

比如像DimDate这种表,表中可能有非常多的属性列用于表示当前日期的一些额外属性,比如下一天的日期,前一天的日期等等。用计算列是一个很好的选择。

参考:

Computed Columns

SQL Server ->> Computed Column(计算列)的更多相关文章

  1. SQL Server中的标识列

    一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列. 该种列具有以下三种特点: .列的数据类型为不带小数的数值类型 .在进行插入(Insert)操作时,该列的值是由 ...

  2. SQL Server自动化运维系列——关于邮件通知那点事(.Net开发人员的福利)

    需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 邮件作为一种非常便利的预警实现方式,在及时性和易用性 ...

  3. SQL Server自动化运维系列——监控跑批Job运行状态(Power Shell)

    需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在上一篇文章中已经分析了SQL SERVER中关于邮 ...

  4. SQL SERVER将某一列字段中的某个值替换为其他的值 分类: MSSQL 2014-11-05 13:11 67人阅读 评论(0) 收藏

    SQL SERVER将某一列字段中的某个值替换为其他的值 UPDATE 表名 SET 列名 = REPLACE(列名 ,'贷','袋') SQL SERVER"函数 replace 的参数 ...

  5. SQL Server 2016:内存列存储索引

    作者 Jonathan Allen,译者 谢丽 SQL Server 2016的一项新特性是可以在“内存优化表(Memory Optimized Table)”上添加“列存储索引(Columnstor ...

  6. SQL Server ->> ColumnStore Index(列存储索引)

    Columnstored index是SQL Server 2012后加入的重大特性,数据不再以heap或者B Tree的形式存储(row level)存储在每一个数据库文件的页里面,而是以列为单位存 ...

  7. Sql Server中的标识列(自增长字段)

    一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列.该种列具有以下三种特点: 1.列的数据类型为不带小数的数值类型2.在进行插入(Insert)操作时,该列的值是由 ...

  8. SQL Server 2012 自动增长列,值跳跃问题

    介绍 从 SQL Server 2012 版本开始, 当SQL Server 实例重启之后,表格的自动增长列的值会发生跳跃,而具体的跳跃值的大小是根据增长列的数据类型而定的.如果数据类型是 整型(in ...

  9. 为SQL Server表中的列添加/修改/删除注释属性(sp_addextendedproperty、sp_updateextendedproperty、sp_dropextendedproperty)

    本篇基本完全参考:sql--sp_addextendedproperty和sp_updateextendedproperty (Transact-SQL) 三个存储过程用法一样,以sp_addexte ...

随机推荐

  1. HTTP请求的常用方法有哪些

    HTTP请求的常用方法有:GET方法.POST方法.HEAD方法.PUT方法.DELETE方法.CONNECT方法.OPTIONS方法.TRACE方法.下面本篇文章就给大家介绍具体介绍一下HTTP请求 ...

  2. Java - n的阶乘计算

    用递归方法,求10!的阶乘 分析: f(n) = n * f(n-1)           n != 1        -----        递推公式 f(n) = 1               ...

  3. JMeter工具接口性能压力测试分析与优化

    最近公司做的项目,要求对相关接口做性能压力测试,在这里记录一下分析解决过程. 压力测试过程中,如果因为资源使用瓶颈等问题引发最直接性能问题是业务交易响应时间偏大,TPS逐渐降低等.而问题定位分析通常情 ...

  4. 08-oracle统计函数(单组分组函数)

    --count时尽量count(列名),count(*)也可以. --count,max,min,sum,avg,median(中位数) select count(empno),count(disti ...

  5. 取消文件与svn服务器的关联

    在使用svn项目管理工具的时候,经常遇到这样的情况: 我从svn下载下来了一个版本,后面不在需要和svn进行同步版本管理,但是文件夹的上面总是有一个勾,显示同步状态,强迫症真的受不了. 效果见小图: ...

  6. GPU体系架构(一):数据的并行处理

    最近在了解GPU架构这方面的内容,由于资料零零散散,所以准备写两篇博客整理一下.GPU的架构复杂无比,这两篇文章也是从宏观的层面去一窥GPU的工作原理罢了 GPU根据厂商的不同,显卡型号的不同,GPU ...

  7. java ee的map

  8. 【.Net】 【C++】容器类型对照

    C# 中主要有两类容器:一个是 System.Array 类(参阅:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/c ...

  9. Java web验证码

    绘制验证码的主要步骤: 1,设置宽度高度,验证码个数,干扰线个数,可选字符,背景颜色,字体格式 2,画干扰线,随机生成颜色,字体,字符 3,设置缓冲区,得到画笔,设置边框,读写数据,存储图片. 1,S ...

  10. 深入理解JavaScript系列(47):对象创建模式(上篇)

    介绍 本篇主要是介绍创建对象方面的模式,利用各种技巧可以极大地避免了错误或者可以编写出非常精简的代码. 模式1:命名空间(namespace) 命名空间可以减少全局命名所需的数量,避免命名冲突或过度. ...