Visualização Indexada
Uma solução totalmente nova baseada em Visualizações Indexadas é possível.
Uma exibição indexada é uma exibição que possui um índice clusterizado e os dados são realmente armazenados em disco.
Pelo que entendi, você está tentando manter uma soma de compras por item de produto armazenada em
tblProduct
. Eu assumi que ItemCode
é o PK de tblProduct e que ItemName
também está definido lá (Não podemos usar MAX
em uma exibição indexada). Assim, podemos definir uma visão como esta: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
Podemos então criar um índice clusterizado nele para mantê-lo no disco. O SQL Server manterá o índice sempre que ocorrer uma atualização na tabela base. Se não houver mais linhas no agrupamento (identificadas por contagem ser 0), a linha será excluída:
CREATE UNIQUE CLUSTERED INDEX PK_vwTotalPurchases ON dbo.vwTotalPurchases (ItemCode);
GO
Agora, se quisermos consultá-lo, podemos juntar esta visão em
tblProducts
(deixe entrar porque pode não haver compras):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;
Podemos definir isso como uma visão também (não indexada, mas uma visão padrão) para que a definição seja utilizável em qualquer lugar.
Observação sobre NOEXPAND
:
Se você não estiver no SQL Server Enterprise ou Developer Edition, deverá usar a dica
WITH (NOEXPAND)
para forçá-lo a usar o índice, caso contrário, ele consultará a base tblPurchase
em vez de. E mesmo nessas edições, é melhor usar NOEXPAND
. Consulte este artigo por Paul White sobre isso.