SQL Server-聚焦计算列或计算列持久化查询性能(二十二)

前言

上一节我们详细讲解了计算列以及计算列持久化的问题,本节我们依然如前面讲解来看看二者查询性能问题,简短的内容,深入的理解,Always to review the basics。

持久化计算列比非持久化计算列性能要好

我们开始创建两个一样的表并都插入100条数据来进行比较,对于计算列我们重新进行创建计算列和非计算列持久化。

CREATE TABLE [dbo].[ComputeColumnCompare] (ID INT,
FirstName VARCHAR(100),
LastName CHAR(8000))
GO
INSERT INTO [dbo].[ComputeColumnCompare] (ID,FirstName,LastName)
SELECT TOP 100  ROW_NUMBER() OVER (ORDER BY a.name) RowID,
'Bob',
CASE WHEN ROW_NUMBER() OVER (ORDER BY a.name)%2 = 1 THEN 'Smith'
ELSE 'Brown' END
FROM sys.all_objects a
CROSS JOIN sys.all_objects b
GO

在ComputeColumn表上创建计算列

USE TSQL2012
GO

ALTER TABLE dbo.ComputeColumn ADD
FullName AS POWER(LEN(LEFT((FirstName+CAST(ID AS VARCHAR(100))),3)), 12)
GO

在ComputeColumnCompare表上创建计算持久化列

USE TSQL2012
GO

ALTER TABLE dbo.ComputeColumnCompare ADD
FullName_P AS POWER(LEN(LEFT((FirstName+CAST(ID AS VARCHAR(100))),3)), 12) PERSISTED
GO

此时我们来运行两个表对计算列和计算列持久化列的查询

复制代码
USE TSQL2012
GO

SELECT FullName
FROM dbo.ComputeColumn
WHERE FullName = 531441
GO
SELECT FullName_P
FROM dbo.ComputeColumnCompare
WHERE FullName_P = 531441
GO
复制代码

此时二者的开销是一样的,只是非持久化列多了一个Compute Scalar操作,主要是因为它计算值是在运行时,此时我们来看看操作成本。

我们看到二者性能还是有一点差异,所以我们能够知道如果计算操作比较复杂时利用持久化来提前进行计算性能会比非持久化列更好。是不是所有情况下持久化列性能都比持久化列性能要好呢?继续往下看。

非持久化计算列比持久化计算列性能要好

我们再来创建测试表并插入1万条数据来进行比较。

复制代码
USE TSQL2012
GO

CREATE TABLE [dbo].[ComputeColumn] (ID INT,
FirstName VARCHAR(100),
LastName CHAR(800))
GO
CREATE TABLE [dbo].[ComputeColumnCompare](ID INT,
FirstName VARCHAR(100),
LastName CHAR(800))
GO
复制代码
复制代码
USE TSQL2012
GO

INSERT INTO  [dbo].[ComputeColumn](ID,FirstName,LastName)
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY a.name) RowID,
'Bob',
CASE WHEN ROW_NUMBER() OVER (ORDER BY a.name)%2 = 1 THEN 'Smith'
ELSE 'Brown' END
FROM sys.all_objects a
CROSS JOIN sys.all_objects b
GO
INSERT INTO [dbo].[ComputeColumnCompare](ID,FirstName,LastName) SELECT TOP
10000 ROW_NUMBER() OVER (ORDER BY a.name) RowID, 'Bob', CASE WHEN ROW_NUMBER() OVER (ORDER BY a.name)%2 = 1 THEN 'Smith' ELSE 'Brown' END FROM sys.all_objects a CROSS JOIN sys.all_objects b GO
复制代码

接下来在两表上创建持久化计算列和非持久化计算列

复制代码
USE TSQL2012
GO

ALTER TABLE dbo.ComputeColumn ADD
FullName AS (FirstName+' '+LastName)
GO

ALTER TABLE dbo.ComputeColumnCompare ADD
FullName_P AS (FirstName+' '+LastName) PERSISTED
GO
复制代码

最后我们进行查询看看查询计划结果

复制代码
USE TSQL2012
GO

SELECT FullName
FROM dbo.ComputeColumn
WHERE FullName = 'Bob Smith'
GO
SELECT FullName_P
FROM dbo.ComputeColumnCompare
WHERE FullName_P = 'Bob Smith'
GO
复制代码

 

到这里我们发现非持久化计算列性能要比持久化计算列性能要好,和上面对照的话我已经明确进行了标记定义列的大小以及插入行的多少是不同的,所以对于持久化列和非持久化列二者并没有绝对性能的谁好谁好,当我们想要看二者谁性能更佳时,我们可能需要考虑定义列的大小、数据行的多少等等。下面我们还看最后一种情况,就是在计算列上来创建索引。

非持久化计算列提高查询性能

我们继续创建测试表

复制代码
USE TSQL2012
GO

CREATE TABLE [dbo].[ComputeColumn] (ID INT,
FirstName VARCHAR(100),
LastName VARCHAR(100))
GO
CREATE TABLE [ComputeColumnCompare] (ID INT,
FirstName VARCHAR(100),
LastName VARCHAR(100))
GO
复制代码
复制代码
USE TSQL2012
GO

INSERT INTO [dbo].[ComputeColumn] (ID,FirstName,LastName)
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY a.name) RowID,
'Bob',
CASE WHEN ROW_NUMBER() OVER (ORDER BY a.name)%2 = 1 THEN 'Smith'
ELSE 'Brown' END
FROM sys.all_objects a
CROSS JOIN sys.all_objects b
GO
INSERT INTO  [dbo].[ComputeColumnCompare](ID,FirstName,LastName)
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY a.name) RowID,
'Bob',
CASE WHEN ROW_NUMBER() OVER (ORDER BY a.name)%2 = 1 THEN 'Smith'
ELSE 'Brown' END
FROM sys.all_objects a
CROSS JOIN sys.all_objects b
GO
复制代码

在ComputeColumn表上创建计算列并创建一个非聚集索引

ALTER TABLE dbo.ComputeColumn ADD
FullName AS (FirstName+' '+LastName)
GO

CREATE NONCLUSTERED INDEX IX_CompCol_CityTrim
ON dbo.ComputeColumn (FullName)
GO

在ComputeColumnCompare表上创建计算列

ALTER TABLE dbo.ComputeColumnCompare ADD
FullName_P AS (FirstName+' '+LastName)
GO

最后查询两个表看看查询计划结果

复制代码
USE TSQL2012
GO

SELECT FullName
FROM dbo.ComputeColumn
WHERE FullName = 'Bob Smith'
GO
SELECT FullName_P
FROM dbo.ComputeColumnCompare
WHERE FullName_P = 'Bob Smith'
GO
复制代码

 

从上述我们知道对计算列创建一个索引能很好的提高查询性能,当然了上述仅仅只是返回计算列,若返回其他列的话可能会导致Key Lookup,但是从另外一个角度来讲还是能提高查询性能,为了解决Key Lookup问题建立太多索引也是有问题的,具体情况具体分析吧。这里并没有比较持久化计算列和非持久化计算列的性能,二者其实是一样的,就没有比较了,只是在利用持久化在数据存储上不同而已。参考资料:【http://blog.sqlauthority.com/2010/08/03/sql-server-computed-column-persisted-and-performance/

总结

到此我们算是结束了对于计算列以及关于计算列持久的概念和性能的分析,下节我们再看看其他查询的知识,接着就进入表表达式的学习,简短的内容,深入的理解,我们下节再会。


为了方便大家在移动端也能看到我分享的博文,现已注册个人公众号,扫描上方左边二维码即可,欢迎大家关注,有时间会及时分享相关技术博文。

感谢花时间阅读此篇文章,如果您觉得这篇文章你学到了东西也是为了犒劳下博主的码字不易不妨打赏一下吧,让楼主能喝上一杯咖啡,在此谢过了!
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!
本文版权归作者和博客园共有,来源网址:http://www.cnblogs.com/CreateMyself)/欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   Jeffcky  阅读(3237)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示