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

SQL Firebird Discussion :

Selection conjointe et montée en charge


Sujet :

SQL Firebird

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    95
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Février 2008
    Messages : 95
    Points : 74
    Points
    74
    Par défaut Selection conjointe et montée en charge
    Bonjour.

    J'ai un petit souci sous Firebird 1.5. J'ai la requête suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MAX(table1.row1) AS result1, MAX(table2.row2) AS result2 FROM table1, table2
    qui fait donc, on a compris, une sélection des deux valeurs maximales sur deux colonnes des deux tableaux.

    Avant, tout marchait très bien. Or, bien sûr j'ai pas fait les tests de montée en charge et au fil du temps, le nombre de colonnes a augmenté d'une centaine à un peu plus de 20 000, et désormais, je ne peux plus exécuter la requête en question.

    Et lorsque je dis que je ne peux plus le faire, c'est que c'est vraiment... impossible. Je l'ai laissé tourner une dizaine de minutes, ça ne donne strictement rien, le processeur est à 100%, pas moyen d'arrêter le truc sauf à arrêter le serveur SQL même.

    Par comparaison, la requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MAX(table1.row1) FROM table1
    et la même pour le deuxième tableau marchent parfaitement bien et prennent à peine une seconde (à peine , sur un site web).


    Dès lors, quelqu'un sait-il pourquoi est-ce que la sélection conjointe fait planter le serveur ?

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Que donne le Plan ?
    un jointure plus explicite sur des Index commun serait peut-être une bonne idée ?
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  3. #3
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    c'est franchement pas terrible comme écriture de requête

    essaie qq chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT SUM(result1) AS result1, sum(result2) AS result2 FROM (
    SELECT MAX(table1.row1) AS result1, 0 AS result2 FROM table1
    UNION
    SELECT 0 AS result1, MAX(table2.row2) AS result2 FROM  table2)
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    95
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Février 2008
    Messages : 95
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Que donne le Plan ?
    un jointure plus explicite sur des Index commun serait peut-être une bonne idée ?
    Pour le plan, j'en sais rien, je trouve pas comment faire sous Firebird.

    Avec un JOIN, oui, ça marche très bien niveau performances. Après, ce n'est pas véritablement ma question.
    Normalement, ce sujet, je l'ai mis dans la catégorie Firebird et il était déplacé, à tort, dans la catégorie SQL, par les modérateurs. Mais justement, ma question était de savoir non pas comment faire pour que ça marche (parce que bon, au fond, rien ne m'empêche aussi de faire deux requêtes séparées ou bien justement de passer par un JOIN), mais pourquoi est-ce que ça marche pas.
    Car si ma requête actuelle totalement inoffensive fait planter le serveur SQL, je ne peux donc nullement savoir quelle autre requête va le planter également, ce qui est quelque peu embêtant.

    essaie qq chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT SUM(result1) AS result1, sum(result2) AS result2 FROM (
    SELECT MAX(table1.row1) AS result1, 0 AS result2 FROM table1
    UNION
    SELECT 0 AS result1, MAX(table2.row2) AS result2 FROM  table2)
    Pareil donc, ça va marcher, mais c'est pas la question.


    Merci en tout cas pour vos réponses.

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    J'essaye de me lancer dans une explication quoique je ne sois pas expert en la matière

    1- Pourquoi j'ai demandé à regarder le plan de la query , tout simplement parce que celui-ci aurait indiqué quels index étaient utilisé pour la jointure non explicite des deux tables . En cas de non indication de la jointure Firebird (corrigez moi si je me trompe) tentera une jointure sur les clés primaires ou sur les noms de champs identiques . En cas de non possibilité de résoudre ce fameux plan et bien je le vois bien faire quelque chose du genre "pour chaque enregistrement de table1 calcule la valeur pour table 2 puis fait la même chose dans l'autre sens" <-- j'exagère peut-être mais à peine D'où le temps d'exécution impossible !!
    ce qui répond également à la constatation
    Avec un JOIN, oui, ça marche très bien niveau performances
    2- Comment voir le Plan . Là , pas de miracle , moi j'utilise le GUI FlameRobin pour tester mes requêtes et ce à ma plus grande satisfaction le seul dommage il reste en anglais , je pense que je vais proposer mes services pour traduction (si possible et dépendant de mes temps libre )
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    95
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Février 2008
    Messages : 95
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    En cas de non possibilité de résoudre ce fameux plan et bien je le vois bien faire quelque chose du genre "pour chaque enregistrement de table1 calcule la valeur pour table 2 puis fait la même chose dans l'autre sens" <-- j'exagère peut-être mais à peine D'où le temps d'exécution impossible !!
    Oui, on dirai. Ca doit pas donner un temps infini dès qu'il y a plus de deux enregistrements par contre ? Car la requête marchait correctement lorsqu'on était à une centaine d'enregistrements dans chaque tableau.

    Comment voir le Plan . Là , pas de miracle , moi j'utilise le GUI FlameRobin pour tester mes requêtes et ce à ma plus grande satisfaction le seul dommage il reste en anglais , je pense que je vais proposer mes services pour traduction (si possible et dépendant de mes temps libre )
    Alors le souci... c'est que le serveur SQL est situé sur une machine qui ne m'appartient pas et sur laquelle il n'est pas question de demander d'installer des logiciels supplémentaires.
    Il faut le faire donc en direct, mais j'ai l'impression, à regarder les exemples sur le net, qu'à chaque fois, la requête même doit être exécutée avant le plan, ce qui est donc bel et bien impossible dans le cas présent. Corrigez-moi si je me trompe...

  7. #7
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par MainMa Voir le message
    Pareil donc, ça va marcher, mais c'est pas la question.
    si justement c'est la question

    suivant comment on écrit la requête, le moteur ne vas pas la traiter de la même manière.
    De même que l'on peut écrire un code inefficace en Delphi, C, etc ..., de même on peut ecrire des select inefficaces

    ta requete avec un cross join est une horreur
    comme si tu disais que le chemin le plus court pour aller de Paris à Lyon était de passer par Brest !
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  8. #8
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par MainMa Voir le message
    Il faut le faire donc en direct, mais j'ai l'impression, à regarder les exemples sur le net, qu'à chaque fois, la requête même doit être exécutée avant le plan, ce qui est donc bel et bien impossible dans le cas présent. Corrigez-moi si je me trompe...
    non la requête n'a pas à être exécutée, juste préparée
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    95
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Février 2008
    Messages : 95
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par makowski Voir le message
    si justement c'est la question

    suivant comment on écrit la requête, le moteur ne vas pas la traiter de la même manière.
    De même que l'on peut écrire un code inefficace en Delphi, C, etc ..., de même on peut ecrire des select inefficaces
    Non mais c'est pas ce que je voulais dire. Que ça soit inefficace, d'accord. Que ça prenne un temps infini, c'est un autre problème. Si deux SELECT séparés me donnent, disons, 5 ms., et la requête en question : 60 ms., je dis rien, j'ai qu'à réfléchir à la manière de faire la sélection. Mais en l'espèce, il ne s'agit pas d'une requête juste lente de fait de son inefficacité, mais d'une requête impossible à exécuter. Je ne sais pas si tu vois la différence...

    comme si tu disais que le chemin le plus court pour aller de Paris à Lyon était de passer par Brest !
    Ben moi, je passe toujours par le Finistère. Faut pas ?

    non la requête n'a pas à être exécutée, juste préparée
    Bon. Vient de lancer la chose, ça tourne depuis dix minutes à 100% du CPU. J'en déduis que... non, en fait, j'en déduis rien du tout.

  10. #10
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par MainMa Voir le message
    J'en déduis que... non, en fait, j'en déduis rien du tout.
    moi j'en déduis que tu n'a pas fait un prepare (c'est à dire juste un calcul du plan, pas l'execution de la requete).
    j'en déduis qu'il faudrait que tu te formes un peu
    que tu te renseigne comment le logiciel que tu utilises fonctionne, comment une requête mal écrite peu effectivement mettre à mal un serveur, de même qu'un programme mal écrit dans n'importe quel langage peu bouffer toutes tes ressources.

    Or ta requete est une horreur, surtout avec la version 1.5 de Firebird

    on ne peut pas balancer comme ça une instruction mal écrite à un serveur en lui disant débrouille toi, j'écris n'importe quoi, mais toi tu dois optimiser, et encore on a pas aborder encore le fait de savoir si ta structure de table est bonne ou pas, sit tu as les index corrects , etc ...

    tu penses avoir écrit qq chose de simple hors c'est le contraire, ta requete avec un cross join fait parti des choses les plus couteuses pour un SGDBR
    alors même que tu pourrais écrire les chose autrement pour que justement, tout ce passe bien et que les temps de réponses soient bons
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    95
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Février 2008
    Messages : 95
    Points : 74
    Points
    74
    Par défaut
    Je te remercie pour ton précieux aide.

    Cordialement.

  12. #12
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par MainMa Voir le message
    Je te remercie pour ton précieux aide.
    de rien

    mais je te redis essaie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT SUM(result1) AS result1, sum(result2) AS result2 FROM (
    SELECT MAX(table1.row1) AS result1, 0 AS result2 FROM table1
    UNION
    SELECT 0 AS result1, MAX(table2.row2) AS result2 FROM  table2)
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    95
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Février 2008
    Messages : 95
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par makowski Voir le message
    de rien

    mais je te redis essaie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT SUM(result1) AS result1, sum(result2) AS result2 FROM (
    SELECT MAX(table1.row1) AS result1, 0 AS result2 FROM table1
    UNION
    SELECT 0 AS result1, MAX(table2.row2) AS result2 FROM  table2)
    Mais je redis que ta requête est très bien et je te remercie, il n'en reste pas moins que ce n'est pas l'objet de la question.

  14. #14
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    et c'est quoi l'objet de la question alors ?
    "pourquoi quand j'écris une mauvaise instruction le serveur à du mal à répondre ?"
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Février 2008
    Messages
    95
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Février 2008
    Messages : 95
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par makowski Voir le message
    et c'est quoi l'objet de la question alors ?
    Ca valait le coup de commencer par là.

    Je explique donc à nouveau, l'objet de la question, c'est pourquoi est-ce que ça prend le temps soit infini soit manifestement trop grand d'exécuter la requête en question. À savoir donc qu'en ayant une sélection simultanée sur deux tables (certes donc, on l'a vu, inefficace), on pouvait s'attendre à un ralentissement, éventuellement considérable, dû à une jointure ou j'en sais trop quoi par rapport aux des sélections distinctes sur deux tableaux pris séparément, mais surement pas à une requête qui dure "autant".

    Enfin, l'hypothèse de SergioMaster va dans ce sens, en tout cas elle me semble fort logique pour expliquer pourquoi le temps d'exécution est sans mesure.

  16. #16
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    c'est pas compliqué à comprendre pourtant
    1/ j'imagine que tes deux champs sur lesquels tu fais le MAX n'ont pas d'index DESC, donc que le plan sera surement NATURAL, donc un scan de toutes les lignes.
    2/ tu utilises la notation FROM table1, table2 sans jointure entre les tables, donc tu fais un CROSS JOIN cf (http://sqlpro.developpez.com/cours/sqlaz/jointures/)
    donc le produit cartésien de deux tables.

    maintenant un exemple avec la table employee de la base exemple de Firebird
    cette table à 42 enregistrements

    que se passe t il si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MAX(T1.EMP_NO) FROM EMPLOYEE T1
    j'ai 42 lectures sur la table employee et un plan T1 Natural

    maintenant ta requete :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MAX(T1.EMP_NO),MAX(T2.EMP_NO) FROM EMPLOYEE T1,EMPLOYEE T2
    1806 lectures ! forcement, puisque tu fais le produit cartésien
    je te laisse faire le calcul avec ton nombre d'enregistrements, mais si c'est 20000 par table, alors cela fait 20 000 * 20 000 = 400 000 000 lectures !

    mon écriture maintenant :
    SELECT SUM(R1), SUM(R2) FROM (
    SELECT MAX(T1.EMP_NO) R1, 0 R2 FROM EMPLOYEE T1
    UNION
    SELECT 0 R1, MAX(T1.EMP_NO) R2 FROM EMPLOYEE T1)
    84 lectures

    maintenant la même chose avec un index desc sur EMP_NO :
    2 lectures !

    je te laisse imaginer les temps de réponses et le cout en ressources à chaque fois.

    voilà c'est aussi simple que ça, clairement ta requête en gros revient à demander au moteur de faire x aller retours paris brest avant d'aller à lyon alors que ton but final est d'aller à lyon
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  17. #17
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Alors là chapeau bas
    ma tentative d'explication est carrément comptabilisée
    toute la différence entre un pro et un néophyte en SGBD
    merci Makowski pour cette explication , sois sur que je m'en resservirai
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Logiciel de test de montée en charge
    Par Avatar dans le forum Outils
    Réponses: 7
    Dernier message: 03/01/2007, 17h23
  2. MOntée en charge ds un modèle multithreading
    Par yanis97 dans le forum Composants VCL
    Réponses: 3
    Dernier message: 23/02/2006, 18h17
  3. Montée en charge quand sql tourne
    Par vvb dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 29/01/2006, 09h30
  4. Tutoriel: Statistiques et montée en charge
    Par RDM dans le forum XMLRAD
    Réponses: 0
    Dernier message: 19/12/2005, 21h53
  5. [outils] Prévoir la montée en charge sur un site ?
    Par ePoX dans le forum Hébergement
    Réponses: 12
    Dernier message: 15/12/2005, 21h01

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