SQL Server ->> Computed Column(计算列)

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

 

转载于:https://www.cnblogs.com/jenrrychen/p/5419035.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现公司->部门->用户多级联动复选框,可以根据上面的示例进行修改。以下是一个简单的示例代码: ```html <template> <uni-form> <uni-form-item label="选择公司"> <uni-checkbox-group v-model="selectedCompanies"> <uni-checkbox v-for="(company, cIndex) in companies" :key="cIndex" :label="company.name"> {{ company.name }} </uni-checkbox> </uni-checkbox-group> </uni-form-item> <uni-form-item label="选择部门"> <uni-checkbox-group v-model="selectedDepartments"> <uni-checkbox v-for="(department, dIndex) in filteredDepartments" :key="dIndex" :label="department.name" :disabled="!selectedCompanies.includes(department.parent)"> {{ department.name }} </uni-checkbox> </uni-checkbox-group> </uni-form-item> <uni-form-item label="选择用户"> <uni-checkbox-group v-model="selectedUsers"> <uni-checkbox v-for="(user, uIndex) in filteredUsers" :key="uIndex" :label="user.name" :disabled="!selectedDepartments.includes(user.parent)"> {{ user.name }} </uni-checkbox> </uni-checkbox-group> </uni-form-item> </uni-form> </template> <script> export default { data() { return { selectedCompanies: [], selectedDepartments: [], selectedUsers: [], companies: [ { name: '公司A', id: '1' }, { name: '公司B', id: '2' }, { name: '公司C', id: '3' }, ], departments: [ { parent: '公司A', name: '部门A1', id: '11' }, { parent: '公司A', name: '部门A2', id: '12' }, { parent: '公司B', name: '部门B1', id: '21' }, { parent: '公司C', name: '部门C1', id: '31' }, { parent: '公司C', name: '部门C2', id: '32' }, ], users: [ { parent: '部门A1', name: '用户A11', id: '111' }, { parent: '部门A1', name: '用户A12', id: '112' }, { parent: '部门A2', name: '用户A21', id: '121' }, { parent: '部门B1', name: '用户B11', id: '211' }, { parent: '部门C1', name: '用户C11', id: '311' }, { parent: '部门C2', name: '用户C21', id: '321' }, ], }; }, computed: { filteredDepartments() { const filteredDepartments = this.departments.filter(department => this.selectedCompanies.includes(department.parent)); return filteredDepartments; }, filteredUsers() { const filteredUsers = this.users.filter(user => this.selectedDepartments.includes(user.parent)); return filteredUsers; }, }, }; </script> ``` 在这个示例中,我们定义了三个选项组(选择公司、选择部门、选择用户),分别对应公司、部门、用户三个级别。我们将选中的公司、部门、用户存储在selectedCompanies、selectedDepartments、selectedUsers数组中,然后通过computed计算属性来动态过滤部门和用户数据。当某个部门或用户的parent值(即所属公司或部门)在selectedCompanies或selectedDepartments数组中时,才会显示相应的复选框,并且其他复选框会被禁用。这样就可以实现公司->部门->用户三级联动复选框的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值