Indexelt nézetek létrehozása
A következőkre vonatkozik:SQL Server
Azure SQL Database
Azure SQL Felügyelt Példány
Ez a cikk azt ismerteti, hogyan hozhat létre indexeket egy nézetben. A nézetben létrehozott első indexnek egyedi fürtözött indexnek kell lennie. Az egyedi fürtözött index létrehozása után több nem fürtözött indexet is létrehozhat. Ha egyedi fürtözött indexet hoz létre egy nézetben, az javítja a lekérdezési teljesítményt, mivel a nézet ugyanúgy tárolódik az adatbázisban, mint egy fürtözött indexet tartalmazó tábla. A lekérdezésoptimalizáló indexelt nézetekkel felgyorsíthatja a lekérdezés végrehajtását. A nézetre nem kell hivatkoznia a lekérdezésben ahhoz, hogy az optimalizáló ezt a nézetet helyettesítőként vegye figyelembe.
Lépések
Az indexelt nézet létrehozásához az alábbi lépések szükségesek, és kritikus fontosságúak az indexelt nézet sikeres megvalósítása szempontjából:
- Ellenőrizze, hogy a
SET
beállítások helyesek-e a nézetben hivatkozott összes meglévő táblához. - A táblák és a nézet létrehozása előtt ellenőrizze, hogy a munkamenet
SET
beállításai megfelelően vannak-e beállítva. - Ellenőrizze, hogy a nézetdefiníció determinisztikus-e.
- Ellenőrizze, hogy az alaptábla tulajdonosa megegyezik-e a nézet tulajdonosával.
- Hozza létre a nézetet a
WITH SCHEMABINDING
beállítással. - Hozza létre az egyedi klaszteres indexet a nézetben.
Ha UPDATE
, DELETE
vagy INSERT
műveleteket (Adatkezelési nyelv vagy DML) hajt végre nagy számú indexelt nézetet vagy kevesebb, de összetett indexelt nézetet tartalmazó táblán, az indexelt nézetekre hivatkozó nézeteket is frissíteni kell. Ennek eredményeképpen a DML-lekérdezési teljesítmény jelentősen csökkenhet, vagy bizonyos esetekben a lekérdezési terv nem is hozható létre.
Ilyen esetekben éles használat előtt tesztelje a DML-lekérdezéseket, elemezze a lekérdezési tervet, és hangolja/egyszerűsítse a DML-utasítást.
Az indexelt nézetekhez szükséges SET-beállítások
Ugyanazon kifejezés kiértékelése eltérő eredményeket eredményezhet az adatbázismotorban, ha a lekérdezés végrehajtásakor különböző SET
beállítások aktívak. Ha például a SET
beállítás CONCAT_NULL_YIELDS_NULL
ON
értékre van állítva, a 'abc' + NULL
kifejezés a NULL
értéket adja vissza. Ha azonban CONCAT_NULL_YIELDS_NULL
OFF
értékre van állítva, ugyanaz a kifejezés abc
hoz létre.
Annak érdekében, hogy a nézetek megfelelően karbantarthatók legyenek, és konzisztens eredményeket adjanak vissza, az indexelt nézetek több SET
beállításhoz rögzített értékeket igényelnek. Az alábbi táblázatban szereplő SET
beállításokat a Required value
oszlopban látható értékekre kell állítani, amikor a következő feltételek lépnek fel:
- Létrejön a nézet és a hozzá tartozó indexek.
- A nézet létrehozásakor a nézetben hivatkozott alaptáblák.
- Ha bármilyen beszúrási, frissítési vagy törlési műveletet hajt végre az indexelt nézetben részt vevő bármely táblán. Ez a követelmény olyan műveleteket is tartalmaz, mint a tömeges másolás, a replikáció és az elosztott lekérdezések.
- A lekérdezésoptimalizáló az indexelt nézetet használja a lekérdezésterv létrehozásához.
BEÁLLÍTÁSOK | Kötelező érték | Alapértelmezett kiszolgálóérték | Alapértelmezett OLE DB és ODBC érték |
Alapértelmezett DB-Library érték |
---|---|---|---|---|
ANSI_NULLS |
ON |
ON |
ON |
OFF |
ANSI_PADDING |
ON |
ON |
ON |
OFF |
ANSI_WARNINGS
1 |
ON |
ON |
ON |
OFF |
ARITHABORT |
ON |
ON |
OFF |
OFF |
CONCAT_NULL_YIELDS_NULL |
ON |
ON |
ON |
OFF |
NUMERIC_ROUNDABORT |
OFF |
OFF |
OFF |
OFF |
QUOTED_IDENTIFIER |
ON |
ON |
ON |
OFF |
1 A ANSI_WARNINGS
beállítása implicit módon beállítja ON
ARITHABORT
elemet ON
értékre.
Ha OLE DB- vagy ODBC-kiszolgálókapcsolatot használ, az egyetlen módosítandó érték a ARITHABORT
beállítás. Minden DB-Library értéket helyesen kell beállítani a kiszolgáló szintjén a sp_configure
vagy az alkalmazásból a SET
paranccsal.
Fontos
Javasoljuk, hogy a ARITHABORT
felhasználói beállítást állítsa ON
kiszolgálószintűre, amint a számított oszlop első indexelt nézete vagy indexe létrejön a kiszolgáló bármely adatbázisában.
Determinisztikus nézetkövetelmény
Az indexelt nézet definíciójának determinisztikuskell lennie. A nézet determinisztikus, ha a kiválasztási listában szereplő összes kifejezés, valamint a WHERE
és GROUP BY
záradékok determinisztikusak. A determinisztikus kifejezések mindig ugyanazt az eredményt adnak vissza, amikor egy adott bemeneti értékkészlettel értékelik ki őket. A determinisztikus kifejezésekben csak determinisztikus függvények vehetnek részt. A DATEADD
függvény például determinisztikus, mert a három paraméterhez tartozó argumentumértékek adott halmazához mindig ugyanazt az eredményt adja vissza.
GETDATE
nem determinisztikus, mert mindig ugyanazzal az argumentummal hívja meg, de a visszaadott érték minden végrehajtáskor megváltozik.
Annak megállapításához, hogy egy nézetoszlop determinisztikus-e, használja a IsDeterministic
függvény tulajdonságát. Annak megállapításához, hogy a sémakötéssel rendelkező nézetben egy determinisztikus oszlop pontos-e, használja a IsPrecise
függvény COLUMNPROPERTY
tulajdonságát.
COLUMNPROPERTY
1
ad vissza, ha TRUE
, 0
FALSE
, és NULL
érvénytelen bemenet esetén. Ez azt jelenti, hogy az oszlop nem determinisztikus vagy nem pontos.
Még ha egy kifejezés determinisztikus is, ha lebegőpontos kifejezéseket tartalmaz, a pontos eredmény a processzor architektúrájától vagy a mikrokód verziójától függ. Az adatintegritás biztosítása érdekében az ilyen kifejezések csak indexelt nézetek nem kulcsoszlopaiként vehetnek részt. A lebegőpontos kifejezéseket nem tartalmazó determinisztikus kifejezéseket pontosnevezik. Csak pontos determinisztikus kifejezések vehetnek részt a kulcsoszlopokban és az indexelt nézetek WHERE
vagy GROUP BY
záradékaiban.
További követelmények
A SET
lehetőségek és a determinisztikus függvénykövetelmények mellett a következő követelményeknek is teljesülniük kell
A
CREATE INDEX
végrehajtó felhasználónak kell lennie a nézet tulajdonosának.Az index létrehozásakor az
IGNORE_DUP_KEY
index beállításánakOFF
(az alapértelmezett beállítás) értékre kell állítania.A táblákra a nézetdefinícióban kétrészes neveknek kell hivatkoznia,
<schema>.<tablename>
.A nézetben hivatkozott felhasználó által definiált függvényeket a
WITH SCHEMABINDING
beállítással kell létrehozni.A nézetben hivatkozott összes felhasználó által definiált függvényre kétrészes névvel kell hivatkozni,
<schema>.<function>
.A felhasználó által definiált függvény adathozzáférési tulajdonságának
NO SQL
kell lennie, a külső hozzáférési tulajdonságnak pedigNO
kell lennie.A közös nyelvi futtatókörnyezeti (CLR) függvények megjelenhetnek a nézet kiválasztási listájában, de nem részei a fürtözött indexkulcs definíciójának. A CLR-függvények nem jelennek meg a nézet
WHERE
záradékában vagy aON
műveletJOIN
záradékában a nézetben.A nézetdefinícióban használt, felhasználó által definiált CLR-típusok CLR-függvényeinek és metódusainak az alábbi táblázatban látható tulajdonságoknak kell lenniük.
Ingatlan Jegyzet DETERMINISZTIKUS = IGAZ Explicit módon deklarálni kell a Microsoft .NET Framework metódus attribútumaként. PREZÍC = IGAZ Kifejezetten a .NET-keretrendszer metódus attribútumaként kell deklarálni. ADATHOZZÁFÉRÉS = NEM SQL A DataAccess
attribútumDataAccessKind.None
ésSystemDataAccess
attribútumSystemDataAccessKind.None
értékre állításával határozható meg.KÜLSŐ HOZZÁFÉRÉS = NEM Ez a tulajdonság alapértelmezés szerint NEM értékű a CLR-rutinok esetében. A nézetet a
WITH SCHEMABINDING
beállítással kell létrehozni.A nézetnek csak olyan alaptáblákra kell hivatkoznia, amelyek ugyanabban az adatbázisban találhatók, mint a nézet. A nézet nem hivatkozhat más nézetekre.
Ha
GROUP BY
van jelen, a VIEW definíciónakCOUNT_BIG(*)
kell tartalmaznia, és nem tartalmazhatHAVING
. Ezek aGROUP BY
korlátozások csak az indexelt nézetdefinícióra vonatkoznak. Egy lekérdezés akkor is használhat indexelt nézetet a végrehajtási tervében, ha nem felel meg ezeknek aGROUP BY
korlátozásoknak.Ha a nézetdefiníció tartalmaz egy
GROUP BY
záradékot, az egyedi fürtözött index kulcsa csak aGROUP BY
záradékban megadott oszlopokra hivatkozhat.A nézetdefiníció
SELECT
utasítása nem tartalmazhat a következő Transact-SQL szintaxist:Transact-SQL függvény Lehetséges alternatívák COUNT
A(z) COUNT_BIG
használataROWSET
függvények (OPENDATASOURCE
,OPENQUERY
,OPENROWSET
ésOPENXML
)Számtani középérték ( AVG
)COUNT_BIG
ésSUM
használata különálló oszlopokkéntStatisztikai összesítő függvények ( STDEV
,STDEVP
,VAR
ésVARP
)null értékű kifejezésre hivatkozó SUM
függvényA ISNULL
belüliSUM()
használata a kifejezés null értékűvé nyilvánításáhozEgyéb összesítő függvények ( MIN
,MAX
,CHECKSUM_AGG
ésSTRING_AGG
)Felhasználó által definiált összesítő függvények (SQL CLR) SELECT záradék Transact-SQL elem Lehetséges alternatíva WITH cte AS
Gyakori táblakifejezések (CTE) WITH
SELECT
Albekérdezések SELECT
SELECT [ <table>. ] *
Az oszlopok kifejezett elnevezése SELECT
SELECT DISTINCT
A(z) GROUP BY
használataSELECT
SELECT TOP
SELECT
OVER
klauzula, amely magában foglalja a rangsorolási vagy összesített ablakfüggvényeketFROM
LEFT OUTER JOIN
FROM
RIGHT OUTER JOIN
FROM
FULL OUTER JOIN
FROM
OUTER APPLY
FROM
CROSS APPLY
FROM
Származtatott táblakifejezések (azaz SELECT
használata aFROM
záradékban)FROM
Öncsatlakozások FROM
Táblaváltozók FROM
Beágyazott táblaértékfüggvény FROM
Többutasítássoros táblaértékes függvény FROM
PIVOT
,UNPIVOT
FROM
TABLESAMPLE
FROM
FOR SYSTEM_TIME
Az időelőzménytáblázat közvetlen lekérdezése WHERE
Teljes szöveges predikátumok ( CONTAINS
,FREETEXT
,CONTAINSTABLE
,FREETEXTTABLE
)GROUP BY
CUBE
,ROLLUP
vagyGROUPING SETS
operátorokKülön indexelt nézetek definiálása GROUP BY
oszlopok egyes kombinációihozGROUP BY
HAVING
Operátorok beállítása UNION
,UNION ALL
,EXCEPT
,INTERSECT
Használja a OR
,AND NOT
ésAND
értékeket aWHERE
záradékban, ebben a sorrendben.ORDER BY
ORDER BY
ORDER BY
OFFSET
Forrásoszlop típusa Lehetséges alternatíva Elavult nagy értékű oszloptípusok (szöveg, ntextés kép) Oszlopok áttelepítése a varchar(max), nvarchar(max), és varbinary(max) típusokra. XML vagy FILESTREAM oszlopok lebegőpontos1 oszlop az indexkulcsban Ritka oszlopkészletek 1 Az indexelt nézet lebegőpontos oszlopokat tartalmazhat; az ilyen oszlopok azonban nem vehetők fel a klaszterezett indexkulcsba.
Fontos
Az indexelt nézetek nem támogatottak az időleges lekérdezéseken (
FOR SYSTEM_TIME
záradékot használó lekérdezéseken).
Javaslatok a datetime és a smalldatetime szolgáltatáshoz
Ha datetime és smalldatetime karakterlánc literálokra hivatkozik indexelt nézetekben, javasoljuk, hogy egyértelmű dátumformátum-stílus használatával explicit módon konvertálja a literálokat arra a dátumtípusra, amelyet szeretne. A determinisztikus dátumformátum-stílusok listáját CAST és CONVERTcímű témakörben találja. A determinisztikus és nemdeterminista kifejezésekről a lap Szempontok szakaszában talál további információt.
A datetime vagy smalldatetime kifejezések, amelyek karaktersztringek implicit konvertálását tartalmazzák, nemdeterminisztikusnak számítanak. További információ: Konstans dátumsztringek nemdeterminisztikus konvertálása DÁTUM értékekké.
Teljesítménybeli szempontok indexelt nézetekkel
Ha DML-t (például UPDATE
, DELETE
vagy INSERT
) hajt végre nagy számú indexelt nézet vagy kevesebb, de összetett indexelt nézet által hivatkozott táblán, ezeket az indexelt nézeteket is frissíteni kell a DML végrehajtása során. Ennek eredményeképpen a DML-lekérdezési teljesítmény jelentősen csökkenhet, vagy bizonyos esetekben a lekérdezési terv nem is hozható létre. Ilyen esetekben éles használat előtt tesztelje a DML-lekérdezéseket, elemezze a lekérdezési tervet, és hangolja/egyszerűsítse a DML-utasítást.
Ha meg szeretné akadályozni, hogy az adatbázismotor indexelt nézeteket használjon, adja meg a OPTION (EXPAND VIEWS) tippet a lekérdezéshez. Ha a felsorolt beállítások bármelyike helytelenül van beállítva, ez a beállítás megakadályozza, hogy az optimalizáló az indexeket használja a nézetekben. További információ a OPTION (EXPAND VIEWS)
tippről: SELECT.
További szempontok
Az indexelt nézetben lévő oszlopok
large_value_types_out_of_row
beállításának beállítása az alaptábla megfelelő oszlopának beállításától öröklődik. Ez az érték sp_tableoptionhasználatával van beállítva. A kifejezésekből formázott oszlopok alapértelmezett beállítása a0
. Ez azt jelenti, hogy a nagy értéktípusok egymás után vannak tárolva.Az indexelt nézetek particionált táblákon hozhatók létre, és maguk is particionálhatók.
A nézet összes indexe eltávolításra kerül, amikor a nézetet eltávolítják. A fürtözött index törlésekor a rendszer törli a nézet összes nem fürtözött indexét és automatikusan létrehozott statisztikáit. A nézet felhasználó által létrehozott statisztikái megmaradnak. A nem klaszterezett indexek egyenként törölhetők. A fürtözött index nézetben való elvetése eltávolítja a tárolt eredményhalmazt, és az optimalizáló visszatér a nézet normál nézetként való feldolgozásához.
A táblákon és nézeteken lévő indexek letilthatók. Ha egy tábla klaszterezett indexe le van tiltva, a táblához társított nézetek indexei is le lesznek tiltva.
Engedélyek
A nézet létrehozásához a felhasználónak rendelkeznie kell a CREATE VIEW
engedéllyel az adatbázisban, és ALTER
engedélyt arra a sémára, amelyben a nézet létrejön. Ha az alaptábla egy másik sémán belül található, a tábla REFERENCES
engedélye minimálisan szükséges. Ha az indexet létrehozó felhasználó eltér a nézetet létrehozó felhasználóktól, az index létrehozásához csak a nézet ALTER
engedélyére van szükség (a séma ALTER
vonatkozik rá).
Indexek csak olyan nézeteken hozhatók létre, amelyek tulajdonosa megegyezik a hivatkozott táblával vagy táblázatokkal. Ezt a fogalmat a nézet és a táblák közötti érintetlen tulajdonjogi láncnak is nevezik. Ha a tábla és a nézet ugyanabban a sémában található, általában ugyanaz a sématulajdonos vonatkozik a sémán belüli összes objektumra. Ezért létrehozhat egy nézetet, és nem lehet a nézet tulajdonosa. Másfelől előfordulhat, hogy a sémán belüli egyes objektumoknak eltérő explicit tulajdonosai vannak. A principal_id
oszlop a sys.tables
-ben akkor tartalmaz értéket, ha a tulajdonos eltér a séma tulajdonosától.
Indexelt nézet létrehozása: T-SQL-példa
Az alábbi példa létrehoz egy nézetet és egy indexet ezen a nézetben, a AdventureWorks
adatbázisban.
--Set the options to support indexed views.
SET NUMERIC_ROUNDABORT OFF;
SET ANSI_PADDING,
ANSI_WARNINGS,
CONCAT_NULL_YIELDS_NULL,
ARITHABORT,
QUOTED_IDENTIFIER,
ANSI_NULLS ON;
--Create view with SCHEMABINDING.
IF OBJECT_ID('Sales.vOrders', 'view') IS NOT NULL
DROP VIEW Sales.vOrders;
GO
CREATE VIEW Sales.vOrders
WITH SCHEMABINDING
AS
SELECT SUM(UnitPrice * OrderQty * (1.00 - UnitPriceDiscount)) AS Revenue,
OrderDate,
ProductID,
COUNT_BIG(*) AS COUNT
FROM Sales.SalesOrderDetail AS od,
Sales.SalesOrderHeader AS o
WHERE od.SalesOrderID = o.SalesOrderID
GROUP BY OrderDate,
ProductID;
GO
--Create an index on the view.
CREATE UNIQUE CLUSTERED INDEX IDX_V1 ON Sales.vOrders (
OrderDate,
ProductID
);
GO
A következő két lekérdezés bemutatja, hogyan használható az indexelt nézet, annak ellenére, hogy a nézet nincs megadva a FROM
záradékban.
--This query can use the indexed view even though the view is
--not specified in the FROM clause.
SELECT SUM(UnitPrice * OrderQty * (1.00 - UnitPriceDiscount)) AS Rev,
OrderDate,
ProductID
FROM Sales.SalesOrderDetail AS od
INNER JOIN Sales.SalesOrderHeader AS o
ON od.SalesOrderID = o.SalesOrderID
AND o.OrderDate >= CONVERT(DATETIME, '05/01/2012', 101)
WHERE od.ProductID BETWEEN 700
AND 800
GROUP BY OrderDate,
ProductID
ORDER BY Rev DESC;
GO
--This query will also use the above indexed view.
SELECT OrderDate,
SUM(UnitPrice * OrderQty * (1.00 - UnitPriceDiscount)) AS Rev
FROM Sales.SalesOrderDetail AS od
INNER JOIN Sales.SalesOrderHeader AS o
ON od.SalesOrderID = o.SalesOrderID
AND o.OrderDate >= CONVERT(DATETIME, '03/01/2012', 101)
AND o.OrderDate < CONVERT(DATETIME, '04/01/2012', 101)
GROUP BY OrderDate
ORDER BY OrderDate ASC;
Végül ez a példa közvetlenül az indexelt nézetből való lekérdezést mutatja be. Az indexelt nézet lekérdezésoptimalizáló általi automatikus használata csak az SQL Server adott kiadásaiban támogatott. Az SQL Server Standard kiadásban a NOEXPAND
lekérdezési tippet kell használnia az indexelt nézet közvetlen lekérdezéséhez. Az Azure SQL Database és az Azure SQL Managed Instance támogatja az indexelt nézetek automatikus használatát a NOEXPAND
tipp megadása nélkül. További információkért lásd: Tábla-javallatok (Transact-SQL).
--This query uses the indexed view directly, on Enterprise edition.
SELECT OrderDate, Revenue
FROM Sales.vOrders
WHERE OrderDate >= CONVERT(DATETIME, '03/01/2012', 101)
AND OrderDate < CONVERT(DATETIME, '04/01/2012', 101)
ORDER BY OrderDate ASC;
--This query uses the indexed view directly, with the NOEXPAND hint.
SELECT OrderDate, Revenue
FROM Sales.vOrders WITH (NOEXPAND)
WHERE OrderDate >= CONVERT(DATETIME, '03/01/2012', 101)
AND OrderDate < CONVERT(DATETIME, '04/01/2012', 101)
ORDER BY OrderDate ASC;
További információ: CREATE VIEW.