上一節咱們詳細講解了計算列以及計算列持久化的問題,本節咱們依然如前面講解來看看兩者查詢性能問題,簡短的內容,深刻的理解,Always to review the basics。sql
咱們開始建立兩個同樣的表並都插入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
USE TSQL2012 GO ALTER TABLE dbo.ComputeColumn ADD FullName AS POWER(LEN(LEFT((FirstName+CAST(ID AS VARCHAR(100))),3)), 12) GO
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操做,主要是由於它計算值是在運行時,此時咱們來看看操做成本。測試
咱們看到兩者性能仍是有一點差別,因此咱們可以知道若是計算操做比較複雜時利用持久化來提早進行計算性能會比非持久化列更好。是否是全部狀況下持久化列性能都比持久化列性能要好呢?繼續往下看。spa
咱們再來建立測試表並插入1萬條數據來進行比較。code
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
接下來在兩表上建立持久化計算列和非持久化計算列orm
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
最後咱們進行查詢看看查詢計劃結果server
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
到這裏咱們發現非持久化計算列性能要比持久化計算列性能要好,和上面對照的話我已經明確進行了標記定義列的大小以及插入行的多少是不一樣的,因此對於持久化列和非持久化列兩者並無絕對性能的誰好誰好,當咱們想要看兩者誰性能更佳時,咱們可能須要考慮定義列的大小、數據行的多少等等。下面咱們還看最後一種狀況,就是在計算列上來建立索引。blog
咱們繼續建立測試表索引
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/】
到此咱們算是結束了對於計算列以及關於計算列持久的概念和性能的分析,下節咱們再看看其餘查詢的知識,接着就進入表表達式的學習,簡短的內容,深刻的理解,咱們下節再會。