D'accord, j'ai donc une procédure stockée de rapport qui fonctionnait incroyablement lente. Les clients se plaignaient que le rapport ne fonctionnerait pas, j'ai commencé à étudier exactement où dans la procédure stockée, le problème était et j'ai trouvé cette partie de 99,8% du temps.
DECLARE @xmlTemp TABLE (
CompanyID INT,
StoreID INT,
StartDate DATETIME,
DateStaID INT,
EndDate DATETIME,
DateEndID INT,
LastUpdate DATETIME)
INSERT INTO @xmlTemp
VALUES (50,
2,
'3/3/2013',
0,
'3/3/2013',
0,
'3/3/2013')
SELECT DISTINCT T.CompanyID,
CompanyName,
Z.StoreID,
StoreName,
CashedOutBy,
TransactionID,
RegisterID,
BusinessDate,
CashedOut,
Total - Isnull((SELECT Sum(DISTINCT PaymentAmount)
FROM vPullDrawerPayments
WHERE CompanyID = T.CompanyID
AND StoreID = T.StoreID
AND TransactionID = T.TransactionID
AND Isnull(PaymentType, 1) <> 1), 0) AS PaymentAmount,
'Cash' AS PaymentDesc,
CASE
WHEN Z.EndDate >= Z.LastUpdate THEN 1
ELSE 0
END AS MissingData
FROM vPullDrawerPayments AS T
INNER JOIN @xmlTemp AS Z
ON T.CompanyID = Z.CompanyID
AND T.StoreID = Z.StoreID
WHERE BusinessDate BETWEEN Z.StartDate AND Z.EndDate
UNION ALL
SELECT DISTINCT NC.CompanyID,
CompanyName,
Z.StoreID,
StoreName,
CashedOutBy,
TransactionID,
RegisterID,
BusinessDate,
CashedOut,
PaymentAmount,
PaymentDesc,
CASE
WHEN Z.EndDate >= Z.LastUpdate THEN 1
ELSE 0
END AS MissingData
FROM vPullDrawerPayments AS NC
INNER JOIN @xmlTemp AS Z
ON NC.CompanyID = Z.CompanyID
AND NC.StoreID = Z.StoreID
WHERE BusinessDate BETWEEN Z.StartDate AND Z.EndDate
AND Isnull(PaymentType, 1) <> 1
UNION ALL
SELECT DISTINCT C.CompanyID,
CompanyName,
Z.StoreID,
StoreName,
CashedOutBy,
TransactionID,
RegisterID,
BusinessDate,
CashedOut,
Sum(Abs(LineAmount)) AS PaymentAmount,
'Coupons' AS PaymentDesc,
CASE
WHEN Max(Z.EndDate) >= Max(Z.LastUpdate) THEN 1
ELSE 0
END AS MissingData
FROM vPullDrawerPayments AS C
INNER JOIN @xmlTemp AS Z
ON C.CompanyID = Z.CompanyID
AND C.StoreID = Z.StoreID
WHERE BusinessDate BETWEEN Z.StartDate AND Z.EndDate
GROUP BY C.CompanyID,
CompanyName,
Z.StoreID,
StoreName,
CashedOutBy,
TransactionID,
RegisterID,
BusinessDate,
CashedOut
La partie @XMLTEpp de cette requête est normalement utilisée pour prendre des paramètres de notre application Web et les transformer en paramètres que le rapport peut réellement utiliser. Par souci de test, je ne fais que insérer des valeurs qui exécutent ceci pour un magasin pendant une journée. Exécution de cette partie peut prendre 20 minutes.
J'ai donc exécuté ce plan de requête via Planexplorer et a vu qu'il traitait toutes les données de deux de mes tables de fait au lieu de filtrer ce magasin et ce jour-là. Comme on le voit dans l'image ci-dessous.
Évidemment c'est mauvais. Donc, la prochaine étape que j'ai prise est de décrocher la jointure The @xml Temp et de placer manuellement les valeurs de la clause de la requête WHERE
pour voir à quel point cela a fonctionné.
SELECT DISTINCT T.CompanyID,
CompanyName,
T.StoreID,
StoreName,
CashedOutBy,
TransactionID,
RegisterID,
BusinessDate,
CashedOut,
Total - Isnull((SELECT Sum(DISTINCT PaymentAmount)
FROM vPullDrawerPayments
WHERE CompanyID = T.CompanyID
AND StoreID = T.StoreID
AND TransactionID = T.TransactionID
AND Isnull(PaymentType, 1) <> 1), 0) AS PaymentAmount,
'Cash' AS PaymentDesc
--CASE WHEN Z.'3/3/2013' >= Z.LastUpdate THEN 1 ELSE 0 END AS MissingData
FROM vPullDrawerPayments AS T
WHERE CompanyID = 50
AND StoreID = 1
AND BusinessDate BETWEEN '3/3/2013' AND '3/3/2013'
UNION ALL
SELECT DISTINCT NC.CompanyID,
CompanyName,
NC.StoreID,
StoreName,
CashedOutBy,
TransactionID,
RegisterID,
BusinessDate,
CashedOut,
PaymentAmount,
PaymentDesc
--CASE WHEN Z.'3/3/2013' >= Z.LastUpdate THEN 1 ELSE 0 END AS MissingData
FROM vPullDrawerPayments AS NC
WHERE CompanyID = 50
AND StoreID = 1
AND BusinessDate BETWEEN '3/3/2013' AND '3/3/2013'
AND Isnull(PaymentType, 1) <> 1
UNION ALL
SELECT DISTINCT C.CompanyID,
CompanyName,
C.StoreID,
StoreName,
CashedOutBy,
TransactionID,
RegisterID,
BusinessDate,
CashedOut,
Sum(Abs(LineAmount)) AS PaymentAmount,
'Coupons' AS PaymentDesc
--CASE WHEN MAX(Z.'3/3/2013') >= MAX(Z.LastUpdate) THEN 1 ELSE 0 END AS MissingData
FROM vPullDrawerPayments AS C
WHERE CompanyID = 50
AND StoreID = 1
AND BusinessDate BETWEEN '3/3/2013' AND '3/3/2013'
GROUP BY C.CompanyID,
CompanyName,
C.StoreID,
StoreName,
CashedOutBy,
TransactionID,
RegisterID,
BusinessDate,
CashedOut
En modifiant cela sur une simple clause où il fonctionne en 4 secondes au lieu de 20 minutes et plus. De plus, le plan de requête montre que le bon est-il une raison pour laquelle je devrais voir ce comportement?
Modifier ici est le lien complet vers le Queryplan .
[Copier de - ma réponse sur sqlperformance.com .]
Quelques grandes suggestions initiales de discussions ailleurs: