Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A következőkre vonatkozik:SQL Server
Azure SQL Database
Felügyelt Azure SQL-példány
SQL-adatbázis a Microsoft Fabricben
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
SETbeá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
SETbeá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 SCHEMABINDINGbeá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_NULLONértékre van állítva, a 'abc' + NULL kifejezés a NULLértéket adja vissza. Ha azonban CONCAT_NULL_YIELDS_NULLOFFértékre van állítva, ugyanaz a kifejezés abchoz 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 ONARITHABORT 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, 0FALSE, é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 INDEXvégrehajtó felhasználónak kell lennie a nézet tulajdonosának.Az index létrehozásakor az
IGNORE_DUP_KEYindex 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 SCHEMABINDINGbeá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 SQLkell lennie, a külső hozzáférési tulajdonságnak pedigNOkell 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
WHEREzáradékában vagy aONműveletJOINzá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 DataAccessattribútumDataAccessKind.NoneésSystemDataAccessattribú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 SCHEMABINDINGbeá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 BYvan jelen, a VIEW definíciónakCOUNT_BIG(*)kell tartalmaznia, és nem tartalmazhatHAVING. Ezek aGROUP BYkorlá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 BYkorlátozásoknak.Ha a nézetdefiníció tartalmaz egy
GROUP BYzáradékot, az egyedi fürtözött index kulcsa csak aGROUP BYzáradékban megadott oszlopokra hivatkozhat.A nézetdefiníció
SELECTutasítása nem tartalmazhat a következő Transact-SQL szintaxist:Transact-SQL függvény Lehetséges alternatívák COUNTA(z) COUNT_BIGhasználataROWSETfüggvények (OPENDATASOURCE,OPENQUERY,OPENROWSETésOPENXML)Számtani középérték ( AVG)COUNT_BIGésSUMhasználata különálló oszlopokkéntStatisztikai összesítő függvények ( STDEV,STDEVPésVARVARP)null értékű kifejezésre hivatkozó SUMfüggvényA ISNULLbelüliSUM()használata a kifejezés null értékűvé nyilvánításáhozEgyéb összesítő függvények ( MIN,MAXésCHECKSUM_AGGSTRING_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 ASGyakori táblakifejezések (CTE) WITHSELECTAlbekérdezések SELECTSELECT [ <table>. ] *Az oszlopok kifejezett elnevezése SELECTSELECT DISTINCTA(z) GROUP BYhasználataSELECTSELECT TOPSELECTOVERklauzula, amely magában foglalja a rangsorolási vagy összesített ablakfüggvényeketFROMLEFT OUTER JOINFROMRIGHT OUTER JOINFROMFULL OUTER JOINFROMOUTER APPLYFROMCROSS APPLYFROMSzármaztatott táblakifejezések (azaz SELECThasználata aFROMzáradékban)FROMÖncsatlakozások FROMTáblaváltozók FROMBeágyazott táblaértékfüggvény FROMTöbbutasítássoros táblaértékes függvény FROMPIVOT,UNPIVOTFROMTABLESAMPLEFROMFOR SYSTEM_TIMEAz időelőzménytáblázat közvetlen lekérdezése WHERETeljes szöveges predikátumok ( CONTAINS,FREETEXT,CONTAINSTABLE,FREETEXTTABLE)GROUP BYCUBE,ROLLUPvagyGROUPING SETSoperátorokKülön indexelt nézetek definiálása GROUP BYoszlopok egyes kombinációihozGROUP BYHAVINGOperátorok beállítása UNION,UNION ALL,EXCEPTINTERSECTHasználja a OR,AND NOTésANDértékeket aWHEREzáradékban, ebben a sorrendben.ORDER BYORDER BYORDER BYOFFSETForrá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_TIMEzá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_rowbeá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.