IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

WinDev Discussion :

[Expériences] Temps d'exécution des requêtes, selon vos configurations et accès


Sujet :

WinDev

  1. #1
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Mars 2002
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2002
    Messages : 899
    Points : 1 103
    Points
    1 103
    Par défaut [Expériences] Temps d'exécution des requêtes, selon vos configurations et accès
    Bonjour à tous et à toutes.

    J'aimerais résumer ici vos expériences de lectures des données.

    Je voudrais comparer les requêtes les plus significatives que vous ayez tenté, sur n'importe quel SGBD (toujours à partir de windev bien entendu).

    Pour ça, il faut
    • la configuration matérielle (brève, mais ça donne une idée de la puissance machine)
    • la charge au moment du test.
    • la méthode utilisée (notamment HLitxxx ou SQLxxx).
    • les données en causes (la requête).
    • la volumétrie.
    • Le temps d'exécution.


    Le résultat intéressant est le temps demandé à l'exécution de la requête, coté serveur (les requêtes en COUNT(*) sont intéressantes pour ça car elles permettent un rapatriement bref du résultat.

    Je commence donc avec mon cas :

    • Serveur dédié HF/CS, version 15 (90F150059b). Cache HF réglé sur 450 Mo. réindexation vient d'être effectuée.
      1. Windows 2008/32bits, pas d'anti-virus ni de pare-feu
      2. Ram 4Go
      3. 2 x Xeon E5420 @ 2.5 Ghz (double quad-core 2.5 Ghz)
      4. 3 x Disques dur en RAID 5 à 10000 tours minutes, 1024 Mo de cache.
    • Seule connexion au serveur au moment du test, serveur HF venant d'être redémarré. Le serveur ne fait rien d'autre.
    • Méthode : exécution par WDSQL
    • Code = compter le nombre de commandes à expédier comprenant une nomenclature : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
       
      SELECT COUNT(DISTINCT Document_ID)
      FROM Document                                --Document = 62 000 lignes, 100 Mo
      INNER JOIN DocumentLigne                     --DocumentLigne = 325 000 lignes, 558 Mo
      ON Document_ID = DocumentLigne_Document_ID
      INNER JOIN Article                           --Article = 21 000 lignes, 46 Mo
      ON Article_ID = DocumentLigne_Article_ID
      WHERE DocumentLigne_Code80 = ''
      AND Document_Type = 3
      AND Article_NomenclatureType_ID = 2
      (les clés de jointures et les conditions sont toutes indexées)

    • Résultat de la requête : 77 lignes
    • Temps d'exécution : 45 secondes la première fois, environ 1 min les suivantes.
      (oui, incroyable, mais les suivantes mettent plus de temps que la première, et j'ai testé plusieurs fois)


    Voila, j'attends vos commentaires et tests avec impatience.

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Bonjour,

    Dans le fond c'est une bonne initiative, cependant mesurer les performances d'une base de données dans l'absolu est infaisable. On a des chiffres mais ils n'ont de sens que dans une comparaison où très peu d'éléments vont varier. Exemples :

    - changement d'index / de paramétrage / de matériel sur une même BD
    - changement de SGBD même structure, mêmes données, même matériel
    - ...

    D'ailleurs tous les benchmarks qu'on peut trouver sont des benchmarks comparatifs. Et encore ils sont souvent critiqués car un parmétrage n'est pas portable à l'identique d'un SGBD à un autre. Bref, très compliqué.

    Je salue cependant l'initiative et vous fournissez des données brutes que les lecteurs seront libres d'interprêter.


    Hors sujet mais vous pouvez tenter les écritures suivantes par curiosité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT COUNT(*) 
    FROM Document 
    WHERE Document.Document_Type = 3
    AND Document.Document_ID IN (SELECT DocumentLigne_Document_ID
    			FROM DocumentLigne
    				INNER JOIN Article                           
    					ON Article_ID = DocumentLigne_Article_ID
    			WHERE DocumentLigne_Code80 = ''
    			AND Article_NomenclatureType_ID = 2
    								)
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT COUNT(*) 
    FROM Document 
    WHERE Document.Document_Type = 3
    AND EXISTS (SELECT 1
    	FROM DocumentLigne
    		INNER JOIN Article                           
    			ON Article_ID = DocumentLigne_Article_ID
    	WHERE DocumentLigne_Document_ID = Document.Document_ID
    	AND DocumentLigne_Code80 = ''
    	AND Article_NomenclatureType_ID = 2
    			)
    Elles devraient être traitées de la même manière mais sait-on jamais, ça pourrait être intéressant.

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 242
    Points : 12 874
    Points
    12 874
    Par défaut
    Bonjour,
    Sur le fond je suis d'accord avec vmonlines, mais pour le fun:
    Serveur:
    Base MaxDB
    Windows 2003 Serveur, 4Gb de RAM
    Bi-Xeon quad core 2.8Ghz
    PV220s, 2*5 disques 36Gb 15krpm en RAID 10, Ultra320 SCSI bicanal (Perc 4 DC, 512Mo de cache)
    Un 1.5 Gb de cache, il y a aussi des bases SqlServeur qui tournent sur ce serveur.
    C'est le serveur de Prod, donc il est en exploitation pendant les tests.
    La requête:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    select s.reference,s.designation,s.metier,s.famille,s.ssfamille,sum(s.memo),sum(s.inv),s.numinv
    from (
    select inventaire.inv_i_num as numinv,sku.art_c_ref as reference,art_c_dgn_lng as designation,c1.cm_c_code as metier,c2.cm_c_code as famille,c3.cm_c_code as ssfamille,0 as memo,sum(li_i_qte) as INV
    from inventaire.inventaire
    inner join inventaire.lig_inv on lig_inv.inv_i_num = inventaire.inv_i_num
    inner join torpedo.sku on sku.sku_c_code = lig_inv.sku_c_code
    inner join torpedo.article on article.art_c_ref = sku.art_c_ref
    inner join torpedo.niv_clfct_mar as c1 on C1.ART_C_REF = ARTICLE.ART_C_REF AND C1.CM_I_NUM = 1 AND C1.CM_I_RANG = 2 
    inner join torpedo.niv_clfct_mar as c2 on C2.ART_C_REF = ARTICLE.ART_C_REF AND C2.CM_I_NUM = 1 AND C2.CM_I_RANG = 3
    left outer join torpedo.niv_clfct_mar as c3 on C3.ART_C_REF = ARTICLE.ART_C_REF AND C3.CM_I_NUM = 1 AND C3.CM_I_RANG = 4 
    where inventaire.inv_i_num = 313 and article.art_l_actif = TRUE 
    group by inventaire.inv_i_num,sku.art_c_ref,art_c_dgn_lng,c1.cm_c_code,c2.cm_c_code,c3.cm_c_code
    union 
    select inventaire.inv_i_num as numinv,sku.art_c_ref as reference,art_c_dgn_lng as designation,c1.cm_c_code as metier,c2.cm_c_code as famille,c3.cm_c_code as ssfamille,sum(ssm_i_qte) as memo,0 as INV
    from inventaire.inventaire
    inner join torpedo.sku_sto_memo on sku_sto_memo.sme_i_num = inventaire.sme_i_num 
    inner join torpedo.sku on sku.sku_c_code = sku_sto_memo.sku_c_code
    inner join torpedo.article on article.art_c_ref = sku.art_c_ref
    inner join torpedo.niv_clfct_mar as c1 on C1.ART_C_REF = ARTICLE.ART_C_REF AND C1.CM_I_NUM = 1 AND C1.CM_I_RANG = 2 
    inner join torpedo.niv_clfct_mar as c2 on C2.ART_C_REF = ARTICLE.ART_C_REF AND C2.CM_I_NUM = 1 AND C2.CM_I_RANG = 3
    left outer join torpedo.niv_clfct_mar as c3 on C3.ART_C_REF = ARTICLE.ART_C_REF AND C3.CM_I_NUM = 1 AND C3.CM_I_RANG = 4 
    where inventaire.inv_i_num = 313 and article.art_l_actif = TRUE 
    group by inventaire.inv_i_num,sku.art_c_ref,art_c_dgn_lng,c1.cm_c_code,c2.cm_c_code,c3.cm_c_code)
    as s 
    where  s.reference not in (select art_c_ref from inventaire.justification where inv_i_num = 313)
    group by s.numinv,s.reference,s.designation,s.metier,s.famille,s.ssfamille  having  sum(s.inv) <> sum(s.memo)

    C'est la requête qui me permet de sortir les écarts pour un inventaire. Elle peut certainement être optimisées, mais elle est construite dynamiquement en fonction des critères de sélections choisis par l'utilisateur.
    La requête est lancée via SqlExec() à travers une connexion ODBC.

    Les tables en question:
    Inventaire: 122
    Lig_inv: 2 927 471
    Article: 80 792
    Sku: 145 924
    Niv_clfct_mar: 681 663
    Sku_Sto_Memo: 1 045 321
    Justification: 30 577

    Et les résultats:
    Temps d'execution: 21 secondes la première fois, 10 secondes la deuxième fois.
    Lignes renvoyées : 1577

    Tatayo.

  4. #4
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Mars 2002
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2002
    Messages : 899
    Points : 1 103
    Points
    1 103
    Par défaut
    Bonjour vmolines, et d'abord merci pour la ré-écriture des requêtes.

    Mon but n'est pas d'établir un comparatif précis des temps d'accès, mais plutôt de dégager un ressentit.
    Mais pour que ce ressentit soit transmis, il faut qu'il s'appuie sur des faits. C'est pour ça que je demande des temps d'accès. Il est en effet très facile de sortir une requête longue, ou une très courte.

    La preuve est que tes optimisations pour mes requêtes ont des temps d'accès très différents. Au lieu d'une minute 10, je passe à 38 secondes pour la première, et résultat erroné pour la seconde.
    (elle ne renvoie aucune ligne, mais je ne suis pas surpris, HF/CS n'aime pas les exists)

    Et merci tatayo d'avoir répondu.

  5. #5
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Pour la requête à base d'exists, tu peux tenter un SELECT * ou un SELECT DocumentLigne_Document_ID car je pense qu'HF n'aime pas le SELECT 1.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    556
    Détails du profil
    Informations personnelles :
    Localisation : Laos

    Informations forums :
    Inscription : Mars 2003
    Messages : 556
    Points : 1 198
    Points
    1 198
    Par défaut
    Histoire d'apporter ma pierre à l'édifice voilà un cas rencontrer sur une migration d'une application HF classic vers SQL-Server.

    On est parti du principe qu'on ne va pas ré-écrire toutes les requêtes et donc l'accès natif devrait suffir....

    La conclusion est plutôt mitigé....

    Les résultats de temps sont tirés grace aux rapports d'optimisations de WD que l'on a passé sur l'appli en HF puis en SQL-Server.

    Pour résumer, les requêtes SQL sont plus rapides, mais ont des temps de préparation et de finalisation plus longs.

    Par exemple, une requête qui met 10 secondes en HF va prendre 0,1 s pour s'initialiser, 0,1 s pour se terminer, et 9,8 s pour s'exécuter.

    En SQL Server, la même requête ne mettra peut être que 4 secondes, 0,25 s pour s'initialiser, 0,25 s pour se terminer et 3,5 s pour s'exécuter.

    Malheureusement, certaines fenêtres ont été écrite en HF pure donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    HFiltre(...)
    HLitPremier(...)
    Tantque
       HLitRecherche (pour simuler un INNER ou un LEFT OUTER selon les cas)
       ...
       HLitRecherche (pour simuler un INNER ou un LEFT OUTER selon les cas)
       ...
    Fin
    HDesactiveFiltre(...)
    Donc au lieu d'avoir une seule requete SQL avec 1 temps d'init + 1 temps de traitement + 1 temps de fermeture

    On se retrouve avec plusieurs fonction Hxxx... qui s'enchaine... donc avec des temps d'init et de fermeture qui explosent...

    donc sur des grosses recherches, SQL-Server est plus lent que HF si c'est une simple conversion brute en utilisant l'accès natif...

    Faire une boucle x10 donne :
    en HF (0,1s + 0,05s + 0,1s) x 10 = 2,5s
    en SQL (0,25s + 0,02s + 0,25s) x 10 = 5,2s

    on s'aperçoit donc que les temps sont multipliés par deux.


    Moralité SQL-Server est plus rapide aussi à condition de coder de manière adapté au type de connexion à la base (ODBC, OLEDB, Accès Natif)

  7. #7
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Salut Ry_Yo

    Ce que tu dis est parfaitement vrai mais je ne trouve pas assez catégorique.

    Les gens qui décident de faire des migrations HF -> SQL Server en se disant qu'SQL Server étant meilleur qu'HF, ils auront de meilleures performances sont à pendre haut et court. Si on utilise une base de données de la manière que tu cites en exemple, il est parfaitement normal d'avoir des performances catastrophiques.

    Il est totalement abhérent d'utiliser une base de données de manière non ensembliste.

    Et je ne dis pas ça pour toi car je crois savoir que tu es très bien placé pour dire comment on doit utiliser SQL Server

Discussions similaires

  1. [AOP] Logger les temps d'exécution des requêtes
    Par HadanMarv dans le forum Spring
    Réponses: 2
    Dernier message: 17/11/2014, 10h39
  2. [WD15] Temps d'exécution des requêtes
    Par thierrybatlle dans le forum WinDev
    Réponses: 7
    Dernier message: 18/02/2010, 16h21
  3. Erreur OEM 10gR2 - Temps d'exécution des requêtes
    Par fabien.morel2002 dans le forum Administration
    Réponses: 0
    Dernier message: 30/11/2009, 16h00
  4. Temps d'exécution des portions de codes
    Par xela dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 23/01/2007, 22h29
  5. Temps d'exécution des instructions FPU
    Par ubi dans le forum Assembleur
    Réponses: 2
    Dernier message: 24/10/2003, 18h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo