SQL Server聚焦点应用主视图多个限定/提议 主视图

摘要:上一节大家简易叙述了表表述式的4类型型,这一系列产品大家来说讲应用主视图的限定,简洁明了的內容,深层次的了解,Always to review the basics。防止在主视图中应用ORDER BY上一节大家...

上一节大家简易叙述了表表述式的4类型型,这一系列产品大家来说讲应用主视图的限定,简洁明了的內容,深层次的了解,Always to review the basics。

防止在主视图中应用ORDER BY

上一节大家也叙述了应用表表述式务必考虑的3个规定,在其中就会有一个没法确保次序,换句话说的ORDER BY的难题,大家還是关键看一下在主视图中的限定。在基本查寻中针对排列大家是那样做的。

USE AdventureWorks2012
SELECT *
FROM Sales.SalesOrderDetail
ORDER BY SalesOrderDetailID DESC

接下去大家在主视图中多数据开展排列,大家建立主视图看来看

USE AdventureWorks2012
IF EXISTS (SELECT * FROM sys.views WHERE OBJECT_ID = OBJECT_ID(N [dbo].[view_limit] ))
DROP VIEW [dbo].[view_limit] GO
CREATE VIEW view_limit
SELECT *
FROM Sales.SalesOrderDetail
ORDER BY SalesOrderDetailID DESC
GO

这时当我们们实行建立主视图时候发觉以下不正确

这时在主视图內部不可以应用ORDER BY大家建立主视图后出外部主视图应用ORDER BY看一下

USE AdventureWorks2012
IF EXISTS (SELECT * FROM sys.views WHERE OBJECT_ID = OBJECT_ID(N [dbo].[view_limit] ))
DROP VIEW [dbo].[view_limit]
CREATE VIEW view_limit
SELECT *
FROM Sales.SalesOrderDetail
SELECT *
FROM view_limit
ORDER BY SalesOrderDetailID DESC

大家再说看一下所述在主视图內部开展ORDER BY时出現的不正确,它表明可使用TOP、OFFSET等,接下去大家运用TOP看来看具体結果是如何的。

USE AdventureWorks2012
IF EXISTS (SELECT * FROM sys.views WHERE OBJECT_ID = OBJECT_ID(N [dbo].[view_limit] ))
DROP VIEW [dbo].[view_limit]
CREATE VIEW view_limit
SELECT TOP 100 PERCENT *
FROM Sales.SalesOrderDetail
ORDER BY SalesOrderDetailID DESC
GO

大家再说查寻该主视图看一下回到的結果集

USE AdventureWorks2012
SELECT * 
FROM dbo.view_limit

当我们们在建立主视图时內部应用ORDER BY对結果集开展降序,結果回到的数据信息根本沒有开展降序,同时大家见到查寻方案压根沒有出現Sort排列实际操作。大家再说看此外一种状况将回到的数据信息设定为比100%少一点试一下看。

IF EXISTS (SELECT * FROM sys.views WHERE OBJECT_ID = OBJECT_ID(N [dbo].[view_limit] ))
DROP VIEW [dbo].[view_limit]
CREATE VIEW view_limit
SELECT TOP 99.9 PERCENT *
FROM Sales.SalesOrderDetail
ORDER BY SalesOrderDetailID DESC
GO

这时则开展了降序排列,表明在主视图中运用TOP、OFFSET就行使了呢?所述查寻大家沒有做一切标准限定,大家查下表格中一共有是多少数据信息和运用主视图查寻时回到有是多少数据信息看一下。

USE AdventureWorks2012
SELECT COUNT(*) AS originalCount
FROM Sales.SalesOrderDetail

FROM dbo.view_limit

尽管在所述状况下大家限定回到的数据信息最后也依照降序来开展排列,它是相对性于小表来讲,假如表格中数据信息量较为大得话,这时根据在主视图中开展ORDER BY得话可能默认设置许多值,因此提议不必在主视图中开展ORDER BY只是在主视图外界开展ORDER BY。好啦它是大家说的第一种限定,大家得出结果。

(1)防止在主视图內部应用ORDER BY,当表数据信息较为钟头尽管根据TOP或OFFSET等能处理难题,可是当数据信息量较为大时这时在主视图內部应用ORDER BY会造成大量的数据信息行缺少,提议在主视图外界开展ORDER BY。

防止在主视图中应用SELECT *

最先大家根据建立主视图看来难题的出現。

USE AdventureWorks2012
IF EXISTS (SELECT * FROM sys.views WHERE OBJECT_ID = OBJECT_ID(N [dbo].[view_limit] ))
DROP VIEW [dbo].[view_limit]
CREATE VIEW view_limit
SELECT *
FROM HumanResources.Shift
GO

接下去大家根据搜索原表和主视图的方法看来看回到的数据信息

USE AdventureWorks2012
-- 搜索原表
SELECT *
FROM HumanResources.[Shift]
-- 搜索主视图
SELECT *
FROM view_limit
GO

恩,没问题,接下去大家在表格中加上附加列

USE AdventureWorks2012
ALTER TABLE HumanResources.[Shift]
ADD AdditionalCol INT
GO

大家再说开展所述查寻,看一下回到的結果集

这时大家发觉加上附加列后主视图仍未显示信息,自然数据信息也也不会显示信息了。这时大家再用主视图查寻以前开展更新看一下

USE AdventureWorks2012
-- 搜索原表
SELECT *
FROM HumanResources.[Shift]
EXEC sp_refreshview view_limit 

GO

这时才可以回到恰当的結果。那麼是啥缘故造成加上附加列根据主视图查寻会出現出乎意料的結果呢,由于主视图在编译程序方法上对列是枚举类型的,而且新的表列不容易全自动加上到主视图中,换句话说若大家附加加上了列,这时列压根不容易加上到主视图中,因此这时大家能够根据sp_refreshview或sp_refreshsqlmodule的方法来更新主视图的数据库。因此大家结果以下

(2)防止在主视图中应用SELECT *,当表格中加上附加列之后造成主视图中不容易全自动开展加上,尽管大家能够根据sp_refreshview或sp_refreshmodule的方法来更新主视图,可是以便防止搞混,最好在主视图界定中显式列举需要要的列的名字,若加上了附加列,同时在主视图中大家必须附加列得话,大家根据ALTER VIEW的方法来改动主视图界定就可以。

主视图查寻回到附加列根据JOIN表造成查寻特性低效

下边大家立即根据事例开展演试。

IF EXISTS (SELECT * FROM sys.views WHERE OBJECT_ID = OBJECT_ID(N [dbo].[view_limit] ))
DROP VIEW [dbo].[view_limit] 

SELECT [SalesOrderID],[SalesOrderDetailID],[CarrierTrackingNumber] ,[OrderQty],sod.[ProductID],[SpecialOfferID],[UnitPrice],[UnitPriceDiscount] ,[LineTotal],[ReferenceOrderID] FROM Sales.SalesOrderDetail sod INNER JOIN Production.TransactionHistory th ON sod.SalesOrderID = th.ReferenceOrderID GO

解出来大家开展基本SQL查寻和主视图查寻

USE AdventureWorks2012
SELECT *
FROM dbo.view_limit
WHERE SalesOrderDetailID 111111
SELECT [SalesOrderID],[SalesOrderDetailID],[CarrierTrackingNumber] ,[OrderQty],sod.[ProductID],[SpecialOfferID],[UnitPrice],[UnitPriceDiscount] ,[LineTotal],[ReferenceOrderID] FROM Sales.SalesOrderDetail sod
INNER JOIN Production.TransactionHistory th ON sod.SalesOrderID = th.ReferenceOrderID
WHERE SalesOrderDetailID 111111
GO

所述运用基本查寻和主视图查寻花销样,可是如今大家有那样一个情景所述主视图是被别的朋友所写,可是当我们们用时还必须回到附加别的列,因此以便不回到别的过剩的数据信息而同事互怼,大家必须再度在主视图外界开展JOIN到来到大家附加的列,大家下边看来看。

USE AdventureWorks2012
SELECT v1.*
,th.[Quantity] FROM dbo.view_limit v1
INNER JOIN Production.TransactionHistory th ON v1.SalesOrderID = th.ReferenceOrderID
WHERE SalesOrderDetailID 111111
SELECT [SalesOrderID],[SalesOrderDetailID],[CarrierTrackingNumber] ,[OrderQty],sod.[ProductID],[SpecialOfferID],[UnitPrice],[UnitPriceDiscount] ,[LineTotal],[ReferenceOrderID] ,th.[Quantity] FROM Sales.SalesOrderDetail sod
INNER JOIN Production.TransactionHistory th ON sod.SalesOrderID = th.ReferenceOrderID
WHERE SalesOrderDetailID 111111
GO

这时附加回到了Quantity列对主视图再度开展JOIN,大家看一下查寻方案花销

这时发觉运用主视图查寻花销大量,而基本查寻但是是多加上一个列罢了沒有一切更改。大家再次向下看

默认设置状况下在主视图上建立数据库索引失效

大家在前边一直探讨通关于数据库索引的创建的难题,并且数据库索引全是创建在表上,那麼大家将数据库索引创建在主视图上状况是如何的呢,不是是查寻高效率会获得提高呢?大家最先建立检测表并插进数据信息

USE AdventureWorks2012
IF EXISTS (SELECT * FROM sys.objects 
WHERE OBJECT_ID = OBJECT_ID(N [dbo].[ViewTable] ) AND TYPE IN (N U ))
DROP TABLE [dbo].[ViewTable]
CREATE TABLE ViewTable (ID1 INT, ID2 INT, SomeData VARCHAR(100))
INSERT INTO ViewTable (ID1,ID2,SomeData)
SELECT TOP 100000 ROW_NUMBER() OVER (ORDER BY o1.name),
ROW_NUMBER() OVER (ORDER BY o2.name),
o2.name
FROM sys.all_objects o1
CROSS JOIN sys.all_objects o2
GO

所述大家建立了检测的主视图表ViewTable并插进了十万条检测数据信息,接下去大家对表创建数据库索引。

USE AdventureWorks2012
CREATE UNIQUE CLUSTERED INDEX [idx_original_table] ON dbo.ViewTable
ID1 ASC
)

接下去大家来建立主视图并在主视图上建立数据库索引

USE AdventureWorks2012
CREATE VIEW ViewLimit
WITH SCHEMABINDING
SELECT ID1,ID2,SomeData
FROM dbo.ViewTable
CREATE UNIQUE CLUSTERED INDEX [idx_view_table] ON [dbo].[ViewLimit]
ID2 ASC
GO

所述大家必须留意,当在主视图上建立数据库索引时务必特定WITH SCHAMABINDING,不然不容许在主视图上建立数据库索引。大家最终根据基本查寻和主视图查寻看来看查寻方案状况

USE AdventureWorks2012
SELECT ID1,ID2,SomeData
FROM dbo.ViewTable
SELECT ID1,ID2,SomeData
FROM dbo.ViewLimit
GO

这时大家发觉主视图查寻运用的数据库索引并不是大家建立的数据库索引idx_view_table,关键缘故是由于主视图和表是关系的,因此查寻方案决策在表上的数据库索引比在主视图上建立的数据库索引更为高效率。 当我们们在WITH中强制性特定noexpand这时可能实行在主视图上建立的数据库索引,由于这时主视图早已和初始表沒有关联,它是单独的,以下:

USE AdventureWorks2012
SELECT ID1,ID2,SomeData
FROM dbo.ViewTable
SELECT ID1,ID2,SomeData
FROM dbo.ViewLimit
WITH(NOEXPAND)
GO

在主视图上建立数据库索引这一难题较为繁杂,大家也不探讨了,一般根据基本查寻都能处理的难题何苦劳驾主视图呢。这一大家必须留意一下就可以了。

这节大家讲了好多个应用主视图时的限定及其提议等难题,下节大家還是会探讨应用主视图的别的限定,简洁明了的內容,深层次的了解,大家下节再相见。



联系我们

全国服务热线:4000-399-000 公司邮箱:343111187@qq.com

  工作日 9:00-18:00

关注我们

官网公众号

官网公众号

Copyright?2020 广州凡科互联网科技股份有限公司 版权所有 粤ICP备10235580号 客服热线 18720358503

技术支持:创建网站