web-dev-qa-db-ja.com

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

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

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を使用しています。

11

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

このビューにはインデックスがないため、ベーステーブルをスキャンします。 enter image description here

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

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

これは適切にビューを使用しました: enter image description here

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

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

追加情報(- Geoff Patterson から)

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

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

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

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

23
beeks