Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Optimisation de requête

2 réponses
Avatar
Phenich Lebao
Bonjour,

J'ai une requête et je sollicite votre aide sur les différentes façons dont
je pourrai l'optimiser.
Voici la requête en question

SELECT A.BS_UNT, 'AP', COUNT(DISTINCT A.VOUCHER_ID)
FROM PS_CTG_LNE A
WHERE A.BS_UNT IN (SELECT F.BS_UNT
FROM P_SEC_CLSA F
WHERE F.OPRCLASS = 'PR_ALL')
AND A.GL_DISTRIB_STATUS <> 'D'
GROUP BY A.BS_UNT
UNION
SELECT B.BS_UNT, 'AM', COUNT(DISTINCT B.ASSET_ID)
FROM PS_DIST_LN B
WHERE B.GL_DISTRIB_STATUS <> 'D'
AND B.FISCAL_YEAR >= YEAR({ fn CURDATE() })-1
AND B.BS_UNT IN (SELECT G.BS_UNT
FROM P_SEC_CLSA G
WHERE G.OPRCLASS = 'PR_ALL')
GROUP BY B.BS_UNT
UNION
SELECT C.BS_UNT, 'AR', COUNT(DISTINCT C.ITEM)
FROM PS_ITEM_DST C
WHERE C.BS_UNT IN (SELECT H.BS_UNT
FROM P_SEC_CLSA H
WHERE H.OPRCLASS = 'PR_ALL')
AND C.GL_DISTRIB_STATUS <> 'D'
GROUP BY C.BS_UNT
UNION
SELECT D.BS_UNT, 'PO', COUNT(DISTINCT D.RECEIVER_ID)
FROM PS_RECV_LN_ACCTG D
WHERE D.BS_UNT IN (SELECT I.BS_UNT
FROM P_SEC_CLSA I
WHERE I.OPRCLASS = 'PR_ALL')
AND D.GL_DISTRIB_STATUS <> 'D'
GROUP BY D.BS_UNT
UNION
SELECT E.BS_UNT, 'IN', COUNT(DISTINCT TRANSACTION_GROUP)
FROM PS_CM_ACCTG_LINE E
WHERE E.GL_DISTRIB_STATUS <> 'D'
AND E.BS_UNT IN (SELECT J.BS_UNT
FROM P_SEC_CLSA J
WHERE J.OPRCLASS = 'PR_ALL')
GROUP BY E.BS_UNT
ORDER BY 1

Merci pour votre soutien

2 réponses

Avatar
Patrice
Bonjour,

Pour une UNION ne pas oublier le ALL si on ne veut pas dédoublonner les
résultats (ce qui fait un travail inutile voire nuisible)...

Sinon, il faut voir le comportement concret de la requête. Notamment comme
c'est une union, il serait facile d'exécuter séparemment chaque portion pour
voir la plus problématique puis de reconstruire pas à pas la portion
concernée pour voir quel est le point qui pose problème.

Un fois ce point localisé,
http://msdn.microsoft.com/fr-fr/library/ms180765.aspx (Affichage du plan
d'exécution) permet de voir le détail de l'exécution de la requête et ce qui
bloque sur ce point et de tester les alternatives (par exemple comparer ce
que donne le IN par rapport à une jointure, l'ajout d'un index manquant
etc...)...

--
Patrice

"Phenich Lebao" a écrit dans le
message de news:
Bonjour,

J'ai une requête et je sollicite votre aide sur les différentes façons
dont
je pourrai l'optimiser.
Voici la requête en question

SELECT A.BS_UNT, 'AP', COUNT(DISTINCT A.VOUCHER_ID)
FROM PS_CTG_LNE A
WHERE A.BS_UNT IN (SELECT F.BS_UNT
FROM P_SEC_CLSA F
WHERE F.OPRCLASS = 'PR_ALL')
AND A.GL_DISTRIB_STATUS <> 'D'
GROUP BY A.BS_UNT
UNION
SELECT B.BS_UNT, 'AM', COUNT(DISTINCT B.ASSET_ID)
FROM PS_DIST_LN B
WHERE B.GL_DISTRIB_STATUS <> 'D'
AND B.FISCAL_YEAR >= YEAR({ fn CURDATE() })-1
AND B.BS_UNT IN (SELECT G.BS_UNT
FROM P_SEC_CLSA G
WHERE G.OPRCLASS = 'PR_ALL')
GROUP BY B.BS_UNT
UNION
SELECT C.BS_UNT, 'AR', COUNT(DISTINCT C.ITEM)
FROM PS_ITEM_DST C
WHERE C.BS_UNT IN (SELECT H.BS_UNT
FROM P_SEC_CLSA H
WHERE H.OPRCLASS = 'PR_ALL')
AND C.GL_DISTRIB_STATUS <> 'D'
GROUP BY C.BS_UNT
UNION
SELECT D.BS_UNT, 'PO', COUNT(DISTINCT D.RECEIVER_ID)
FROM PS_RECV_LN_ACCTG D
WHERE D.BS_UNT IN (SELECT I.BS_UNT
FROM P_SEC_CLSA I
WHERE I.OPRCLASS = 'PR_ALL')
AND D.GL_DISTRIB_STATUS <> 'D'
GROUP BY D.BS_UNT
UNION
SELECT E.BS_UNT, 'IN', COUNT(DISTINCT TRANSACTION_GROUP)
FROM PS_CM_ACCTG_LINE E
WHERE E.GL_DISTRIB_STATUS <> 'D'
AND E.BS_UNT IN (SELECT J.BS_UNT
FROM P_SEC_CLSA J
WHERE J.OPRCLASS = 'PR_ALL')
GROUP BY E.BS_UNT
ORDER BY 1

Merci pour votre soutien
Avatar
Fred BROUARD
Bonjour,

0) comme déjà dit, utilisez UNION ALL

1) commencez par éviter les fonctions ODBC comme { fn CURDATE() },
remplacez les par des fonctions SQL Server comme CURRENT_TIMESTAMP ou
GETDATE

2) préfixez toutes vos tables par leur schéma SQL. A défaut dbo.

3) pour chacune des requêtes vérifiez s'il existe des index couvrant,
sinon, rélisez les.
Exemple pour la première requête :
CREATE INDEX X01 ON dbo.PS_CTG_LNE (BS_UNT, VOUCHER_ID)
INCLUDE (GL_DISTRIB_STATUS);
CREATE INDEX X02 ON dbo.P_SEC_CLSA (OPRCLASS, BS_UNT);

A +


Phenich Lebao a écrit :
Bonjour,

J'ai une requête et je sollicite votre aide sur les différentes façons dont
je pourrai l'optimiser.
Voici la requête en question

SELECT A.BS_UNT, 'AP', COUNT(DISTINCT A.VOUCHER_ID)
FROM PS_CTG_LNE A
WHERE A.BS_UNT IN (SELECT F.BS_UNT
FROM P_SEC_CLSA F
WHERE F.OPRCLASS = 'PR_ALL')
AND A.GL_DISTRIB_STATUS <> 'D'
GROUP BY A.BS_UNT
UNION
SELECT B.BS_UNT, 'AM', COUNT(DISTINCT B.ASSET_ID)
FROM PS_DIST_LN B
WHERE B.GL_DISTRIB_STATUS <> 'D'
AND B.FISCAL_YEAR >= YEAR({ fn CURDATE() })-1
AND B.BS_UNT IN (SELECT G.BS_UNT
FROM P_SEC_CLSA G
WHERE G.OPRCLASS = 'PR_ALL')
GROUP BY B.BS_UNT
UNION
SELECT C.BS_UNT, 'AR', COUNT(DISTINCT C.ITEM)
FROM PS_ITEM_DST C
WHERE C.BS_UNT IN (SELECT H.BS_UNT
FROM P_SEC_CLSA H
WHERE H.OPRCLASS = 'PR_ALL')
AND C.GL_DISTRIB_STATUS <> 'D'
GROUP BY C.BS_UNT
UNION
SELECT D.BS_UNT, 'PO', COUNT(DISTINCT D.RECEIVER_ID)
FROM PS_RECV_LN_ACCTG D
WHERE D.BS_UNT IN (SELECT I.BS_UNT
FROM P_SEC_CLSA I
WHERE I.OPRCLASS = 'PR_ALL')
AND D.GL_DISTRIB_STATUS <> 'D'
GROUP BY D.BS_UNT
UNION
SELECT E.BS_UNT, 'IN', COUNT(DISTINCT TRANSACTION_GROUP)
FROM PS_CM_ACCTG_LINE E
WHERE E.GL_DISTRIB_STATUS <> 'D'
AND E.BS_UNT IN (SELECT J.BS_UNT
FROM P_SEC_CLSA J
WHERE J.OPRCLASS = 'PR_ALL')
GROUP BY E.BS_UNT
ORDER BY 1

Merci pour votre soutien




--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
Enseignant aux Arts & Métiers PACA et à L'ISEN Toulon - Var Technologies
*********************** http://www.sqlspot.com *************************