最近发现项目中的SQL的WHERE部分有很多的计算列,例如:
USE AdventureWorks2014 SELECT 1 FROM dbo.Person WHERE FirstName+‘ ‘+LastName=‘Diane Margheim‘
所以针对这个部分进行下优化,所以打算采用计算列的方式,但是又没有证明到底可不可行,所以发表下该文章发表下自己的理解也希望各位大神能点出不足的地方.
以下是针对计算列性能优化的证明:
先填充数据
USE AdventureWorks2014 GO SELECT * INTO dbo.person FROM Person.Person GO
第一种情况,无计算列情况
SET STATISTICS IO ON SET STATISTICS TIME ON DBCC FREEPROCCACHE DBCC DROPCLEANBUFFERS GO SELECT 1 FROM dbo.Person WHERE FirstName+‘ ‘+LastName=‘Diane Margheim‘ GO
第二种情况,添加计算列
ALTER TABLE dbo.Person ADD fullName AS (FirstName +‘ ‘+ LastName)
SET STATISTICS IO ON SET STATISTICS TIME ON DBCC FREEPROCCACHE DBCC DROPCLEANBUFFERS GO SELECT 1 FROM dbo.Person WHERE FirstName+‘ ‘+LastName=‘Diane Margheim‘ GO
再次查询
SET STATISTICS IO ON SET STATISTICS TIME ON DBCC FREEPROCCACHE DBCC DROPCLEANBUFFERS GO SELECT 1 FROM dbo.Person WHERE FirstName+‘ ‘+LastName=‘Diane Margheim‘ GO
从信息和查询计划可得知,添加计算列以后不会带来性能上的提升
第三种情况,给计算列设置为持久,再次尝试
ALTER TABLE dbo.Person ADD fullName AS (FirstName +‘ ‘+ LastName) PERSISTED
SET STATISTICS IO ON SET STATISTICS TIME ON DBCC FREEPROCCACHE DBCC DROPCLEANBUFFERS GO SELECT 1 FROM dbo.Person WHERE FirstName+‘ ‘+LastName=‘Diane Margheim‘ GO
将计算列设置可持久化以后效能会有一个提升(预读15次)
第四种情况,不持久化的情况下给计算列添加索引
CREATE INDEX ix_index_fullName ON dbo.Person(fullName)
SET STATISTICS IO ON SET STATISTICS TIME ON DBCC FREEPROCCACHE DBCC DROPCLEANBUFFERS GO SELECT 1 FROM dbo.Person WHERE FirstName+‘ ‘+LastName=‘Diane Margheim‘ GO
从讯息可得知,添加了索引以后,查询提高一个数量级,
第五种情况,持久化的情况下给计算列添加索引
已经对性能提高微乎其微了。
所以针对以上五种情况可得知:
计算列(持久化或者不持久化)添加索引以后可以对SQL性能有所提高。
PS:持久化会增大本地的物理存储空间
以上是我对计算列性能提高所带来的证明,如果有不足,还请指点,谢谢:)
时间: 2024-10-07 00:29:26