SQL Serverのインデックス付きビュー


11

私はテーブルとそれにインデックス付きビューを持っています

Create table mytable1 (ID int identity(1,1), Name nvarchar(100))

Create table mytable2 (ID int identity(1,1), Name nvarchar(100))

Create view myview 
with schemabinding 
as 
   select a.name, b.name
   from mytable1 a 
   join mytable2 b on a.Id = b.Id

次のクエリを実行すると

select a.name, b.name
from mytable1 a 
join mytable2 b on a.Id = b.Id

インデックス付きビューを使用しません。SQL Serverに代わりにインデックス付きビューを使用させるヒント(またはその他の方法)はありますか?

私には大きなシステムがあり、それを最適化する必要があります。テーブルではなくビューから選択するようにすべてのSQLスクリプトを変更することはできません。インデックス付きビューを作成し、SQL Serverにテーブルではなくビューからデータを取得させます。

SQL Server 2014 Enterprise Editionを使用しています。


私には大きなシステムがあり、それを最適化する必要があります。すべてのSQLスクリプトを変更して、テーブルではなくビューから選択することはできません。インデックス付きビューを作成し、SQLサーバーにテーブルではなくビューからデータを取得するように強制します。
Artashes Khachatryan 2015

回答:


23

SQL Serverで常にインデックス付きビューを作成して、既存の製品を調整しています。適切な列を利用している場合、オプティマイザは十分に賢く、インデックスを使用できます。

この例を使用すると、ビューを作成したように見えますが、実際にはビューにインデックスを作成していません。

if object_id(N'mytable1') is not null 
drop table mytable1
if object_id(N'mytable2') is not null 
drop table mytable2
go

Create table mytable1 (ID int identity(1,1), Name1 nvarchar(100))
GO
Create table mytable2 (ID int identity(1,1), Name2 nvarchar(100))
GO

insert into mytable1 values ('steve')
insert into mytable1 values ('jack') 
insert into mytable1 values ('mike') 
insert into mytable1 values ('ralph') 
insert into mytable1 values ('simon')

insert into mytable2 values ('smith')
insert into mytable2 values ('jackson') 
insert into mytable2 values ('mikaelson') 
insert into mytable2 values ('montalvo') 
insert into mytable2 values ('singer')
go

if object_id(N'myview') is not null
drop view myview
go

Create view myview 
with schemabinding 
as 
select a.id, a.name1, b.name2
from dbo.mytable1 a 
join dbo.mytable2 b on a.Id = b.Id
GO

select a.name1, b.name2
from mytable1 a join mytable2 b on a.Id = b.Id
GO

このビューにはインデックスがないため、ベーステーブルをスキャンします。 ここに画像の説明を入力してください

しかし、インデックスを追加すると、オプティマイザはそれを使用できます。

CREATE UNIQUE CLUSTERED INDEX [ix_cl_names] ON [myview]
(
    [name1] ASC,
    [name2] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

これは適切にビューを使用しました: ここに画像の説明を入力してください

テーブルではなくビューから選択するようにすべてのSQLスクリプトを変更することはできません。インデックス付きビューを作成し、SQL Serverにテーブルではなくビューからデータを取得させます。

クエリで参照されていないときにSQL Serverがインデックス付きビューを使用するように強制するヒントやその他の方法はありません。

追加情報Geoff Pattersonから)

この場合、オプティマイザはEnterprise Editionのみでインデックス付きビューをNOEXPAND使用できますが、使用されているビューインデックスを100%確認する必要がある場合は、ヒントを使用してビューを直接参照することは意味があります。 Standard Editionで使用したい場合。

Enterprise Editionでもクエリを頻繁に見ましたが、オプティマイザは、ビューインデックスが使用されない限り使用できるという事実を認識しませんNOEXPAND。これは複雑なクエリでより一般的ですが、単純なクエリでも発生する可能性があります。

ポールホワイトは、私がのニュアンスを探求した中で読んだ優れた記事の 1つを持っていますNOEXPAND。ヒントは、ビューインデックスの使用だけでなく、インデックス付きビューで統計が自動的に作成されるかどうか、プランの基数の見積もりなどにも影響を与える可能性があります。

そしてZaneから:補足として、更新、挿入、および削除の時間に追加される他のインデックスと同様に、インデックス付きビューに注意してください。


-5

アプリケーションコードを新しいオブジェクト名に変更できない場合は、アプリケーションユーザーを変更して、新しい既定のスキーマを使用し、同じオブジェクト名を使用して別のスキーマにインデックス付きビューを作成できますか?例えば:

create view iv.MyTest 
as 
 select Col1, Col2 from dbo.MyTest 

もちろん、これは、アプリケーションコードでスキーマ名を使用していない場合にのみ機能します。

持っている場合は、すべてのオブジェクトを新しいスキーマに移動して、代わりに古いスキーマのビューを導入することができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.