Bonjour, (au fait, lire les règles du forum en haut de chaque page (règles de politesse, version logicielle, etc.))
Avant de parler INDEX, déjà ne pas faire du SELECT * et préciser les colonnes que l'on veut voir remonter.
Ensuite, sauf si tu as un serveur poussif ou une térachiée de données, c'est le genre de requête qui répond assez bien (sur 900 000 lignes de docs, j'ai un résultat en moins d'1/4 de seconde, donc, faut pas être trop difficile).
Et puis, en SQL (mais là, vaut mieux s'adresser aux spécialistes sur des sites full SQL), les statistiques générées par le serveur optimisent la remontée des résultats (plus on fait de fois une même requête, ou approchante, mieux les statistiques fournissent le meilleur chemin de résolution au moteur SQL).
Lance 2 fois la requête et, en général, la seconde fois, les résultats sortent plus vite...
Sinon, pour le codage des champs cbXXX, pas très sorcier, Codage ASCII de la chaine, il me semble.
Bon, et puis, maintenant que je suis lancé ...
On peut imaginer optimiser en passant d'abord par une sélection des entêtes (il y en a moins que de ligne en général) puis faire la jointure sur le do_Type et le cbdo_Piece ....
Mais les résultats ne sont pas toujours ceux escomptés !
Une attaque directe des F_DOCLIGNE, comme tu le fais, mais avec sélection des 'bons' champs semble le plus efficace (voir dernière requête).
Exemple de code pour vérifier les temps de réponse :
- Code: Tout sélectionner
Declare @tStart datetime2
Declare @tEnd datetime2
Declare @sMsg varchar(500)
-- * Jointure
Set @sMsg= '* avec jointure '
Set @tStart=SYSDATETIME()
SELECT *
FROM F_DOCENTETE
INNER JOIN F_DOCLIGNE ON F_DOCENTETE.cbDO_Piece = F_DOCLIGNE.cbDO_Piece AND F_DOCENTETE.DO_Type=F_DOCLIGNE.DO_Type
Set @tEnd=SYSDATETIME()
Print @sMsg + CAST(DATEDIFF(millisecond,@tStart,@tEnd) AS VARCHAR(50)) + ' millisecondes'
-- Champs nommés + Jointure
Set @sMsg= 'Champs nommés + Jointure '
Set @tStart=SYSDATETIME()
SELECT F_DOCENTETE.DO_Type, F_DOCENTETE.DO_Piece, F_DOCLIGNE.AR_Ref, F_DOCLIGNE.DL_Qte
FROM F_DOCENTETE
INNER JOIN F_DOCLIGNE ON F_DOCENTETE.cbDO_Piece = F_DOCLIGNE.cbDO_Piece AND F_DOCENTETE.DO_Type=F_DOCLIGNE.DO_Type
Set @tEnd=SYSDATETIME()
Print @sMsg + CAST(DATEDIFF(millisecond,@tStart,@tEnd) AS VARCHAR(50)) + ' millisecondes'
-- * sur F_DOCLIGNE
Set @sMsg= '* sur F_DOCLIGNE '
Set @tStart=SYSDATETIME()
SELECT * FROM F_DOCLIGNE
Set @tEnd=SYSDATETIME()
Print @sMsg + CAST(DATEDIFF(millisecond,@tStart,@tEnd) AS VARCHAR(50)) + ' millisecondes'
-- Champs nommés + Jointure + clause WHERE sur DO_Type
Set @sMsg= 'Champs nommés + Jointure sur DO_Type=7 '
Set @tStart=SYSDATETIME()
SELECT F_DOCENTETE.DO_Type, F_DOCENTETE.DO_Piece, F_DOCLIGNE.AR_Ref, F_DOCLIGNE.DL_Qte
FROM F_DOCENTETE
INNER JOIN F_DOCLIGNE ON F_DOCENTETE.cbDO_Piece = F_DOCLIGNE.cbDO_Piece
WHERE F_DOCENTETE.DO_Type=7
Set @tEnd=SYSDATETIME()
Print @sMsg + CAST(DATEDIFF(millisecond,@tStart,@tEnd) AS VARCHAR(50)) + ' millisecondes'
-- * sur F_DOCLIGNE sur DO_Type=7
Set @sMsg= '* sur F_DOCLIGNE sur DO_Type=7 '
Set @tStart=SYSDATETIME()
SELECT * FROM F_DOCLIGNE
WHERE DO_Type=7
Set @tEnd=SYSDATETIME()
Print @sMsg + CAST(DATEDIFF(millisecond,@tStart,@tEnd) AS VARCHAR(50)) + ' millisecondes'
-- Champs nommés + Jointure + Where Do_Type et DO_Piece
Set @sMsg= 'Champs nommés + Jointure + Where Do_Type et DO_Piece '
Set @tStart=SYSDATETIME()
SELECT F_DOCENTETE.DO_Type, F_DOCENTETE.DO_Piece, F_DOCLIGNE.AR_Ref, F_DOCLIGNE.DL_Qte
FROM F_DOCENTETE
INNER JOIN F_DOCLIGNE ON F_DOCENTETE.cbDO_Piece = F_DOCLIGNE.cbDO_Piece
WHERE F_DOCENTETE.DO_Type=7 AND F_DOCENTETE.DO_Piece='FA009433'
Set @tEnd=SYSDATETIME()
Print @sMsg + CAST(DATEDIFF(millisecond,@tStart,@tEnd) AS VARCHAR(50)) + ' millisecondes'
-- Champs nommés sur F_DOCLIGNE + Where Do_Type et DO_Piece
Set @sMsg= '* sur F_DOCLIGNE + Where Do_Type et DO_Piece '
Set @tStart=SYSDATETIME()
SELECT * FROM F_DOCLIGNE
WHERE DO_Type=7 AND DO_Piece='FA009433'
Set @tEnd=SYSDATETIME()
Print @sMsg + CAST(DATEDIFF(millisecond,@tStart,@tEnd) AS VARCHAR(50)) + ' millisecondes'
-- Champs nommés sur F_DOCLIGNE + Where Do_Type et DO_Piece
Set @sMsg= 'Champs sur F_DOCLIGNE + Where Do_Type et DO_Piece '
Set @tStart=SYSDATETIME()
SELECT DO_Type,DO_Piece,AR_Ref,DL_Qte FROM F_DOCLIGNE
WHERE DO_Type=7 AND DO_Piece='FA009433'
Set @tEnd=SYSDATETIME()
Print @sMsg + CAST(DATEDIFF(millisecond,@tStart,@tEnd) AS VARCHAR(50)) + ' millisecondes'
Résultats :
- Code: Tout sélectionner
(893130 ligne(s) affectée(s))
* avec jointure 128321 millisecondes
(893130 ligne(s) affectée(s))
Champs nommés + Jointure 8557 millisecondes
(893130 ligne(s) affectée(s))
* sur F_DOCLIGNE 65823 millisecondes
(420147 ligne(s) affectée(s))
Champs nommés + Jointure sur DO_Type=7 3975 millisecondes
(420147 ligne(s) affectée(s))
* sur F_DOCLIGNE sur DO_Type=7 31618 millisecondes
(10 ligne(s) affectée(s))
Champs nommés + Jointure + Where Do_Type et DO_Piece 407 millisecondes
(10 ligne(s) affectée(s))
* sur F_DOCLIGNE + Where Do_Type et DO_Piece 279 millisecondes
(10 ligne(s) affectée(s))
Champs sur F_DOCLIGNE + Where Do_Type et DO_Piece 143 millisecondes
Configuration de test :
- Code: Tout sélectionner
Machine :
* HP ProBook 4330s
* Core i3-2330M / 2.20GHz
* 4 Go RAM
* Indice de performance = 4.7 (voir 5.9 hors Aero)
Système :
* Windows Seven x64 SP1 Pro (toutes mises à jour système effectuées)
Sage version :
* Sage Etp 16.05
Base de données :
* Microsoft Std 2008 SP1 (celui fourni par l'éditeur SAGE) limité à 2Go de RAM
* Mode de récupération : Simple
* Niveau de compatibilité : SQL Server 2000 (80)
(Bref, configuration de base selon préco. éditeur)
* Nombre de documents = 91271 / nombre de lignes de documents = 893130
(c'est pas bijou ...)
Bref, c'est bien souvent l'environnement qui pénalise les temps de réponse (SQL mal paramétré pour SAGE, problèmes de lenteurs réseau (résolution DNS ou un vieux switch qui traîne par là) (on en voir de toute les couleurs))
Essaye d'effectuer ces tests directement sur le serveur SQL, puis (en ayant installé le SQL Client pour lancer le SQL Management Studio sur un poste client) à partir d'un poste réseau.
Cela peut démontrer de défaillance coté paramétrage réseau.
Ces petits exemples m'ont occupé environ 2H, tu me dois donc 2x1452.99€ (et encore, là, je ne compte pas en millisecondes
)
Pour ma gouverne, es-tu un utilisateur SAGE (client ou service informatique client), un revendeur SAGE, un CCS SAGE ou autre ?
Cordialement,