Commentaires

  1. Avatar de henrif
    • |
    • permalink
    Citation Envoyé par laurentSc
    Sinon, peux-ty donner le code complet de cette requête :
    Par exemple, pour 3 enregistrements :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    INSERT INTO `t_video` (`video_title`, `video_support`, `video_multilingual`, `video_chapter`, `video_year`, `video_summary`, `video_stock`) 
    VALUES 
      ('The Lord of the Rings - The Fellowship of the Ring', 'BLU-RAY', '1', '1', '2001', '', '10'), 
      ('The Lord of the Rings - The two towers', 'BLU-RAY', '1', '2', '2002', '', '0'), 
      ('The Lord of the Rings - The return of the King', 'DVD', '1', '3', '2003', '', '1')
    C'est la requête classique d'insertion d'un lot de valeurs dans une table , tel qu'on la trouve dans un dump sql d'une table (généré par exemple un export avec PhpMyAdmin).

    Mais peut être ai-je soulevé un faux problème ?
    En pratique, je ne vois pas de cas où on aurait besoin de faire une boucle sur l'insertion multiple de valeurs dans une même table hormis l'historisation de données, la synchronisation d'une table. Si le script php a déjà mis en forme les data dans une table la requête multiple comme ci dessus sera plus rapide (en veillant quand même à ne pas dépasser la taille maxi d'une requête sql).
    L’utilisation des emplacements nommés (:variable) ou des marqueurs de positionnement (?) est peut être plus pertinente sur des requêtes de sélection (SELECT...).

    EDIT du 27 Mai

    Avec un peu de réflexion, une instruction INSERT implique une écriture dans les fichiers de la table, ce qui est couteux en temps (accès aux fichiers...). La seule façon d'optimiser est de regrouper les insertions d'une même table à l'aide de la requête multiple indiquée au dessus, de façon à n'avoir qu'un seul accès en écriture. La couche PDO et le passage des valeurs par référence n'apporte rien puisque l'exécution de la requête entrainera une écriture sur les fichiers. Boucler sur des requêtes INSERT entraine plusieurs écritures donc une performance moindre.

    Par contre une requête de recherche (SELECT), surtout multi critères, nécessite des tris sur les tables d'index et la couche PDO par le mécanisme de préparation va mettre en cache ces opérations. Celles-ci ne seront pas refaites lors d'un nouvel appel à la même requête avec des valeurs différentes.
    Mis à jour 27/05/2020 à 10h03 par henrif (Après réflexion...)
  2. Avatar de laurentSc
    • |
    • permalink
    Si j'avais transmis la réponse de rawsrc, c'est qu'il vient de quitter dvp, et je le joins par e-mail...

    Sinon, peux-ty donner le code complet de cette requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $sql     = <<<sql
    INSERT INTO t_video (video_title, video_support, video_multilingual, video_chapter, video_year, video_summary, video_stock) 
         VALUES (values1.....),
                     (values2....)...
    sql;
    J'ai pas le courage de l'écrire...
  3. Avatar de henrif
    • |
    • permalink
    Citation Envoyé par laurentSc
    Je transmets la réponse de rawsrc :

    Le mécanisme de préparation a un énorme avantage sur le passage d'une seul et unique SQL très longue, c'est l'optimisation et la mise en cache qui est faite par le moteur de base de données.
    Le plan d'exécution de la requête n'est calculé qu'une seule et unique fois. Après les mécanismes d'optimisations s'enclenchent automatiquement à chaque tour.
    Je préfère de loin utiliser les requêtes préparées paramétrées que du SQL brut quand il y a plusieurs tours de boucle à réaliser.
    Sans compter que question lecture du SQL tu y gagnes à être concis.
    Je reviens sur les performances de l'exemple donné , à savoir la boucle php:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $sql     = <<<sql
    INSERT INTO t_video (video_title, video_support, video_multilingual, video_chapter, video_year, video_summary, video_stock) 
         VALUES ({$in($title)}, {$in($support)}, {$in($multilingual, 'bool')}, {$in($chapter, 'int')}, {$in($year, 'int')}, {$in($summary)}, {$in($stock, 'int')})
    sql;
     
    foreach ($data as $film) {
        extract($film);
        $ids[] = $ppp->insert($sql);    // à la fin : [1, 2, 3] : nos 3 films ont bien été ajoutés
    }
    vs la requête unique avec plusieurs lignes de valeurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // boucle de construction de la requête à partir du tableau $data pour obtenir 
    $sql     = <<<sql
    INSERT INTO t_video (video_title, video_support, video_multilingual, video_chapter, video_year, video_summary, video_stock) 
         VALUES (values1.....),
                     (values2....)...
    sql;
    
    $stmt2 = $dbh->prepare($query); 
    $stmt2->execute();
    Mon environnement et PHP 7 et Mysql 5, donc pas universel, mais assez courant pour les sites web.
    J'ai fait quelques mesures de temps d'exécution avec hrtime() et la première méthode prend nettement plus de temps : environ 2 fois plus pour 3 enregistrements , 5 fois plus pour 10, 15 fois plus pour 100 !
    La fonction mysqli $dbh->query($query) prend elle 2 fois plus de temps que PDO. Ouf !

    Bref, je ne suis pas convaincu de l'optimisation due au passage par référence des variables ?!...
  4. Avatar de bouye
    • |
    • permalink
    Oui c'est assez surprenant je trouve

    Il est possible qu'ils aient assez de clients demandant un support commercial pour que ce soit viable. Ou alors ils ont du mal a adapter leurs autres produits a des versions plus récentes de Java... et je doute que leur SGBD puisse supporter une cadence de maj a vitesse grand V comme celle qu'ils nous imposent.
  5. Avatar de Mickael Baron
    • |
    • permalink
    Merci Fabrice pour ce retour.

    J'ai comme l'impression que Java 8 est encore très utilisé pour que Oracle recule la fin du support.

    Mickael
  6. Avatar de autran
    • |
    • permalink
    Je confirme l'intérêt de ce site.
    Mais il impose de n'utiliser que les (excellents) objets de l'API WEKA
  7. Avatar de gerard093
    • |
    • permalink
    Pour les gens intéressés par les algorithmes de data sciences, je recommande d'aller faire un tour sur le site de weka.

    En effet, les applications de data sciences sont accompagnées d'un générateur de code qui permet de mettre en oeuvre des applications java à moindre coût. Et c'est open source ...

    https://www.cs.waikato.ac.nz/ml/weka/
  8. Avatar de laurentSc
    • |
    • permalink
    J'ai mis au point (c'est testé) une requête qui fait un insert et évite les doublons (si une clé unique est déjà présente dans la table, UPDATE à la place de INSERT) :

    Code php : 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
    $ppp = new PDOPlusPlus(PDOPlusPlus::MODE_PREPARE_PARAMS);
                $in = $ppp->injector(); // injecteur de référence
                $ids = [];
                $sql = <<<sql
    INSERT INTO t_video ( video_title, video_support, video_multilingual, video_chapter, video_year, video_summary, video_stock) 
         VALUES ( {$in($title)}, {$in($support)}, {$in($multilingual,
                    'bool')}, {$in($chapter,
                    'int')}, {$in($year,
                    'int')}, {$in($summary)}, {$in($stock,
                    'int')})
         ON DUPLICATE KEY UPDATE video_title={$in($title)},video_support= {$in($support)},video_multilingual= {$in($multilingual,
                    'bool')},video_chapter={$in($chapter,
                    'int')},video_year={$in($year,
                    'int')},video_summary={$in($summary)},video_stock= {$in($stock,
                    'int')}
    sql;
     
                foreach ($data
                         as
                         $film)
                {
                    extract($film);
                    $ids[] = $ppp->insert($sql);    // à la fin : [1, 2, 3] : nos 3 films ont bien été ajoutés
                }
  9. Avatar de laurentSc
    • |
    • permalink
    Je transmets la réponse de rawsrc :

    Le mécanisme de préparation a un énorme avantage sur le passage d'une seul et unique SQL très longue, c'est l'optimisation et la mise en cache qui est faite par le moteur de base de données.
    Le plan d'exécution de la requête n'est calculé qu'une seule et unique fois. Après les mécanismes d'optimisations s'enclenchent automatiquement à chaque tour.
    Je préfère de loin utiliser les requêtes préparées paramétrées que du SQL brut quand il y a plusieurs tours de boucle à réaliser.
    Sans compter que question lecture du SQL tu y gagnes à être concis.
  10. Avatar de henrif
    • |
    • permalink
    Bonjour rawsrc,

    Avant tout, grand merci pour le partage.
    Je débute dans l'utilisation de PDO, je suis bien loin de maitriser les appels des fonctions de cette classe.

    J'ai une question sur le paragraphe 8.3 ÉCHAPPEMENT AVEC LE MÉCANISME DE PRÉPARATION ET PASSAGE DES VALEURS PAR RÉFÉRENCE, où il s'agit d'insérer plusieurs enregistrements dans la table sql.

    En terme de performance d'accès à la base sql, ne vaut-il pas mieux faire une seule requête avec plusieurs enregistrements, de la forme :
    INSERT INTO `table` (`col1`, `col2`, ...) VALUES
    ('value1col1',....), ('value2col1',....), ('value3col1',....)

    plutôt que de faire une boucle php générant plusieurs requêtes sql ?