J'échège à l'aide de l'indice READPAST
pour réduire le verrouillage des ressources dans le sous-système financier de notre demande.
Cela semblait être un bon moyen d'y aller car les enregistrements de transactions financières ne sont jamais ajoutés, jamais mis à jour ou supprimés. Les seules lignes qui seraient jamais sautées sont de nouvelles lignes neuves insérées à l'intérieur d'une transaction; Ils n'existent efficacement pas au monde extérieur jusqu'à ce que la transaction soit commise.
Cependant, j'ai remarqué que les pires performances sur les requêtes utilisent des vues indexées que j'avais placé le READPAST
indice sur. Comparaison des plans de requête, on dirait avec l'indice, l'optimiseur de requête choisit de ne pas utiliser la vue indexée et redevient plutôt de le traiter comme une vue régulière.
Je ne sais pas pourquoi cela serait; J'imagine que les vues indexées soient comme n'importe quel autre index de ces clés peuvent être verrouillées pendant les opérations et ajouter READPAST
fonctionnerait de la même manière.
SELECT TOP 1 isa.InvoiceId
FROM Financial_InvoiceSummaryAmounts isa WITH (READPAST)
WHERE isa.TotalOwedAmount = 0.0
SELECT TOP 1 isa.InvoiceId
FROM Financial_InvoiceSummaryAmounts isa
WHERE isa.TotalOwedAmount = 0.0
Ajout d'un NOEXPAND
L'indice semble aussi fonctionner, mais je suis intéressé à en apprendre davantage sur la raison éventuellement pourquoi READPAST
a amené l'optimiseur de requête à faire ce choix en premier lieu (dans le cadre d'une partie intégrante réponse).
Réutiliser l'exemple de table et de la vue indexée de mon article ne autre raison d'utiliser NOEXPAND
astuces dans l'édition d'entreprise :=:
CREATE TABLE dbo.T
(
col1 integer NOT NULL
);
GO
INSERT dbo.T WITH (TABLOCKX)
(col1)
SELECT
SV.number
FROM master.dbo.spt_values AS SV
WHERE
SV.type = N'P';
GO
CREATE VIEW dbo.VT
WITH SCHEMABINDING
AS
SELECT T.col1
FROM dbo.T AS T;
Cette requête correspond à la vue indexée (bien qu'avec un agrégat redondant):
SELECT DISTINCT
VT.col1
FROM dbo.VT AS VT;
Ajouter un READPAST
Astuce donne accès à la table de base:
SELECT DISTINCT
VT.col1
FROM dbo.VT AS VT
WITH (READPAST);
Le READPAST
indice est affectant sémantique. L'optimiseur résiste à la réécriture des requêtes telles que les résultats changent. Pour illustrer:
La requête suivante s'exécute sans problèmes:
SELECT DISTINCT
VT.col1
FROM dbo.VT AS VT
WITH (READPAST);
Pourtant:
SELECT DISTINCT
VT.col1
FROM dbo.VT AS VT
WITH (READPAST)
OPTION
(TABLE HINT (VT, FORCESCAN));
Produit l'erreur:
[.____] MSG 8722, niveau 16, état 1, ligne 42 [.____] ne peut pas exécuter la requête. Mais pas dans la clause "Table d'indice" correspondante. [.____
Lorsque vous référenciez la vue indexée sans l'indice NOEXPAND
, la vue est développée (avant que la compilation et l'optimisation ne commence) pour référencer les objets sous-jacents à la place. Plus tard dans le processus, l'optimiseur peut envisager de faire correspondre l'arbre de requête à une vue indexée, en tout ou en partie.
Lorsque READPAST
est utilisé sans NOEXPAND
, l'indice - propagate à la table de base, empêchant la correspondance de vue (différentes sémantiques).
Avec NOEXPAND
, l'indice s'applique directement à la vue, donc il n'y a pas de problème.