5

それぞれ約500k行の(そして成長している)2つのテーブルがあります。挿入/更新はこれらに対して常に発生し、場合によっては1分あたり100回発生します。これらのテーブルへの基本的な挿入で、システムにパフォーマンスの問題、つまりタイムアウトが発生しています。インデックスを調整し、通常の最適化を行いました。しかし、これらの2つのテーブルが5つのビューで参照されており、結合が多いという事実が有害である可能性があるのではないかと思います。基になるテーブルが変わると、それらを参照するビューも変わるといつも思っていました。したがって、テーブルが大幅に変更されている場合は、キャッチアップ更新ビューを絶えず再生する必要があるため、システムが圧倒されている可能性があります。

4

4 に答える 4

12

それらが索引付けされたビューでない限り(質問でそのようなことについて言及していません)、それらはまったく「更新」されません。

通常のビューはCのマクロに似ています。これらは、より大きな式の一部を非表示にするための便利な省略形です。それらは、それらを参照するステートメントの解析ツリーに展開され、ツリー全体がコンパイルされ、使用時に最適化されます。


インデックス付きビューの場合、おおむね正しいでしょう。ビューは、ベーステーブルで変更を実行する同じトランザクションの一部として維持されます。ただし、インデックス付きビューのルールは、この更新アクティビティで大きなペナルティが発生しないように設計されています(ベーステーブル全体を再クエリすることなく維持できます)。

于 2013-02-11T15:28:37.987 に答える
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

実行プラン(SSMS:Ctrl + M) ここに画像の説明を入力してください を見ると、ビュー(FROM Sales.v_SalesOrderDetail v)が展開され、サーバーが2つのテーブルSales.SalesOrderDetail dとをクエリしていることがわかりますProduction.Product pSales.SalesOrderHeader hさらに、との間の結合がどのようにSales.SalesOrderDetail d削除されるかを確認できます。理由は次のとおりです。

  • SELECT句( )には、テーブルのSELECT v.SalesOrderDetailID, v.OrderQty, v.UnitPrice, v.ProductName列が含まれていません。Sales.SalesOrderHeader

  • この2つのテーブルの間には、外部キー制約があり、

  • このFK制約は信頼されています。

2)ビューにインデックスが付けられており(UNIQUE CLUSTERED INDEXビューに定義が定義されていることを意味します)、SQL Serverエディションがエンタープライズの場合、ビューは展開される場合と展開されない場合があります。エディション<>エンタープライズの場合、インデックス付きビューが展開されます。ヒントを使用して、サーバーに[インデックス付き]ビューを展開しないように強制できます。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

ここに画像の説明を入力してください この場合、実行プランにClustered Index Scan PK_v_SalesOrderDetail2オペレーターが含まれていることがわかります 。したがって、2番目のビューで定義されたインデックスを使用します。

注意:SQLServerのバグインデックスビュー+MERGE

于 2013-02-11T16:10:21.847 に答える
4

SQLServerビューはキャッシュされないため、ビューを要求するたびにクエリが実行されます

于 2013-02-11T15:11:22.930 に答える
-1

インデックスの調整は適切ですが、これらのインデックスの統計を更新する頻度と時期を検討する価値があるかもしれません。また、バッファテーブルを使用して、5分または10分ごと、またはシステムに適したものを一括操作として挿入できる挿入を保持すると役立つ場合があります(これを別の物理ディスクに配置することをお勧めします)。 90%の時間ではるかに高速に選択し、他の10%の時間で現在よりもそれほど悪くはありません。

于 2016-06-08T10:25:35.657 に答える