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

简介: 前言 上一节我们详细讲解了计算列以及计算列持久化的问题,本节我们依然如前面讲解来看看二者查询性能问题,简短的内容,深入的理解,Always to review the basics。 持久化计算列比非持久化计算列性能要好 我们开始创建两个一样的表并都插入100条数据来进行比较,对于计算列我们重新进行创建计算列和非计算列持久化。

前言

上一节我们详细讲解了计算列以及计算列持久化的问题,本节我们依然如前面讲解来看看二者查询性能问题,简短的内容,深入的理解,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/

总结

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

目录
相关文章
|
SQL 关系型数据库 MySQL
mysql 简单的sql语句,入门级增删改查
介绍MySQL中的基本SQL语句,包括数据的增删改查操作,使用示例和简单的数据表进行演示。
mysql 简单的sql语句,入门级增删改查
|
JavaScript 物联网 API
vue中使用mqtt
vue中使用mqtt
|
7月前
|
人工智能 安全 数据安全/隐私保护
落实《安全生产法》,企业隐患排查如何实现闭环管理
落实制度靠流程,而流程能不能闭环,很大程度上取决于工具是不是够简洁。在隐患排查这件事上,复杂不一定代表先进,能落地、能用起来、能留下记录,才是关键。
|
SQL 索引
在 SQL Server 中使用 STRING_AGG 函数
【8月更文挑战第5天】
4199 2
在 SQL Server 中使用 STRING_AGG 函数
|
人工智能 JavaScript 程序员
Fitten Code:在VSCode插件市场备受欢迎的原因是什么?
随着AI技术的不断发展,AI在编写代码方面的能力也日益强大。充分利用AI的能力能够显著提高代码编写的效率和质量。今天我将向大家介绍一款备受瞩目的AI代码神器——Fitten Code,让我们一同揭开它神秘的面纱!
1194 3
|
存储 文字识别 算法
解析!文档扫描 SDK 中的高级图像处理技术
本博客讨论了图像质量在文档扫描中的重要性,解决了扫描过程中遇到的常见挑战,以及文档扫描 SDK 利用先进的图像处理技术来应对这些挑战。
AC/DC电源模块的工作原理基于一系列的电子组件和电路
AC/DC电源模块的工作原理基于一系列的电子组件和电路
AC/DC电源模块的工作原理基于一系列的电子组件和电路
|
安全 测试技术 网络安全
|
JSON JavaScript 前端开发
JavaScript中操作后端用ModelAndView返回的List数据
在 JavaWeb 项目中,我们经常使用 ModelAndView 装入请求页面的地址和传入页面的数据,我们在 HTML 中可以用 JSTL 来操作装入在 ModelAndView 中的 List 数据
525 0