zoukankan      html  css  js  c++  java
  • 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/

    总结

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

  • 相关阅读:
    PHP 基础复习 2018-06-21
    PHP 基础复习 2018-06-17
    php 基础复习 2018-06-20
    [Android] ImageView.ScaleType设置图解
    Android中滑屏实现----触摸滑屏以及Scroller类详解 .
    Android Scroller简单用法 --View滚动
    Android下如何理解onMeasure,onLayout的过程
    ( 转)从四分钟到两秒——谈谈客户端性能优化的一些最佳实践
    8种形式的Android Dialog使用举例
    Android加载图片导致内存溢出(Out of Memory异常)
  • 原文地址:https://www.cnblogs.com/CreateMyself/p/6184749.html
Copyright © 2011-2022 走看看