SQL Server视图何时更新?

Kan*_*ves 3 sql-server view

我有两个表,每个表大约500k行(并且正在增长).插入/更新不断发生,有时每分钟100次.该系统在这些表的基本插入方面存在性能问题,即超时.我们调整了索引,并完成了通常的优化.但我想知道这两个表是否在5个视图中被引用并加入大量事实可能是有害的.我一直认为,也许是错误的,随着基础表的变化,引用它们的视图也会发生变化.因此,如果表格发生了这么大的变化,也许我们的系统不得不不断地进行追赶更新视图.

Dam*_*ver 12

除非他们是索引视图(你没有在你的问题中提到这些),否则他们根本不会"更新".

普通视图类似于C中的宏 - 它们只是隐藏较大表达式的一部分的便捷缩写.它们被扩展到任何语句引用它们的解析树中,然后在使用时编译和优化整个树.


对于索引视图,您将在很大程度上正确 - 视图将作为执行基表中更改的同一事务的一部分进行维护.但是,已设计索引视图的规则,以便此更新活动不会产生太大的惩罚(可以维护它们而无需重新查询整个基表).


Bog*_*ean 5

这取决于:

1) 如果视图没有被索引,则视图被展开

-- View definition
CREATE VIEW Sales.v_SalesOrderDetail
AS
SELECT  h.SalesOrderID, h.SalesOrderNumber, h.OrderDate, 
        d.SalesOrderDetailID, d.OrderQty, d.UnitPrice, d.LineTotal, 
        p.ProductID, p.Name AS ProductName, p.Color AS ProductColor
FROM    Sales.SalesOrderHeader h
INNER JOIN Sales.SalesOrderDetail d ON h.SalesOrderID = d.SalesOrderID
INNER JOIN Production.Product p ON d.ProductID = p.ProductID
GO

-- View usage
SELECT  v.SalesOrderDetailID, v.OrderQty, v.UnitPrice, v.ProductName
FROM    Sales.v_SalesOrderDetail v
WHERE   v.ProductColor='Red';
GO
Run Code Online (Sandbox Code Playgroud)

如果我们看一下执行计划(SSMS:Ctrl + M), 在此处输入图片说明 然后我们将看到视图 ( FROM Sales.v_SalesOrderDetail v) 被展开并且服务器只查询两个表:Sales.SalesOrderDetail dProduction.Product p。更多,我们可以看到Sales.SalesOrderHeader h和之间的连接Sales.SalesOrderDetail d是如何被删除的,因为:

  • SELECT条款(SELECT v.SalesOrderDetailID, v.OrderQty, v.UnitPrice, v.ProductName)不包括来自列Sales.SalesOrderHeader表,

  • 在这两个表之间有一个外键约束和

  • 这个 FK 约束是可信的。

2) 如果视图被索引(意味着视图上有一个UNIQUE CLUSTERED INDEX定义)并且 SQL Server 版本是企业版,那么视图可以扩展或不扩展。如果版本 <> 企业,则扩展索引视图。我们可以使用提示强制服务器不扩展[indexed] 视图NOEXPAND

-- View definition
CREATE VIEW Sales.v_SalesOrderDetail2
WITH SCHEMABINDING
AS
SELECT  h.SalesOrderID, h.SalesOrderNumber, h.OrderDate, 
        d.SalesOrderDetailID, d.OrderQty, d.UnitPrice, d.LineTotal, 
        p.ProductID, p.Name AS ProductName, p.Color AS ProductColor
FROM    Sales.SalesOrderHeader h
INNER JOIN Sales.SalesOrderDetail d ON h.SalesOrderID = d.SalesOrderID
INNER JOIN Production.Product p ON d.ProductID = p.ProductID
GO

-- Defining the UNIQUE CLUSTERED INDEX
CREATE UNIQUE CLUSTERED INDEX PK_v_SalesOrderDetail2
ON Sales.v_SalesOrderDetail2 (SalesOrderDetailID);
GO

-- View usage
SELECT  v.SalesOrderDetailID, v.OrderQty, v.UnitPrice, v.ProductName
FROM    Sales.v_SalesOrderDetail2 v WITH (NOEXPAND)
WHERE   v.ProductColor='Red';
GO
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们可以看到执行计划 在此处输入图片说明 包括Clustered Index Scan PK_v_SalesOrderDetail2运营商。因此,它使用在第二个视图上定义的索引。

请注意:SQL Server 错误索引视图 + MERGE