Indexované zobrazení
Zcela nové řešení založené na Indexovaná zobrazení je možné.
Indexované zobrazení je zobrazení, které má seskupený index a data jsou ve skutečnosti uložena na disku.
Pokud tomu dobře rozumím, snažíte se zachovat součet nákupů na položku produktu uložený v tblProduct
. Předpokládal jsem, že ItemCode
je PK produktu tblProduct a ItemName
je zde také definován (Nemůžeme použít MAX
v indexovaném zobrazení). Můžeme tedy definovat pohled takto:
CREATE VIEW dbo.vwTotalPurchases
WITH SCHEMABINDING -- must be schema bound, we cannot change underlying columns after creation
AS
SELECT
ItemCode,
SUM(Quantity) QuantityPurchased,
COUNT_BIG(*) CountPurchases -- if we group, must have count also, so that rows can be maintained
FROM dbo.tblPurchase -- must use two-part names
GROUP BY itemCode;
GO
Poté na něm můžeme vytvořit seskupený index, který jej uchová na disku. SQL Server bude udržovat index vždy, když dojde k aktualizaci základní tabulky. Pokud v seskupení nejsou žádné další řádky (identifikované podle počtu 0), řádek se smaže:
CREATE UNIQUE CLUSTERED INDEX PK_vwTotalPurchases ON dbo.vwTotalPurchases (ItemCode);
GO
Nyní, pokud se na to chceme dotazovat, můžeme se nechat připojit k tomuto pohledu na tblProducts
(připojit se vlevo, protože nemusí probíhat žádné nákupy):
SELECT
p.ItemCode,
p.ItemName,
ISNULL(tp.QuantityPurchased, 0) QuantityPurchased,
ISNULL(tp.CountPurchases, 0) CountPurchases
FROM tblProducts p
LEFT JOIN vwTotalPurchases tp WITH (NOEXPAND) ON tp.ItemCode = p.ItemCode;
Můžeme to definovat také jako pohled (ne indexovaný, ale standardní pohled), takže definice je použitelná kdekoli.
Poznámka k NOEXPAND
:
Pokud nepoužíváte SQL Server Enterprise nebo Developer Edition, musíte použít nápovědu WITH (NOEXPAND)
vynutit použití indexu, jinak se bude dotazovat na základní tblPurchase
namísto. A i v těchto edicích je nejlepší použít NOEXPAND
.
Viz tento článek od Paula Whitea.