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

Bibliothèques et frameworks PHP Discussion :

Gérer des créations d'entité en bulk


Sujet :

Bibliothèques et frameworks PHP

  1. #1
    Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2020
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Avril 2020
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Gérer des créations d'entité en bulk
    Bonjour à tous,

    Je travaille sur une application pour laquelle nous avons une entité "view", une entité "column", une entité "row" et une entité "cell". "cell" est associé à "column" et "row" qui sont toutes deux associées à "view". Le but est de modéliser un tableau.

    Dans ce contexte, nous avons parfois des insertions "massives" de "row" et "cell" et je cherche à A - optimiser le process / B - exécuter les requêtes en asynchrone.

    Pour la partie A, j'ai réduit au maximum le code et passe par du dbal avec les lignes suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // Pass an array structured as followed :
    // Warning put a comma on each row except last one
    // Array (
    //     "(cell_row_id,column_row_id,'value')",
    //     "(cell_row_id,column_row_id,'value')",
    //     "(cell_row_id,column_row_id,'value')",
    // )
    public function insertRawRows($row,Connection $connection)
    {
            $connection->query("
            INSERT INTO cell (id,value,cell_row_id,cell_column_id)
            VALUES
                " . implode(',', $row) . ";
            ");
    }
    C'est pas mal mais ça reste trop bloquant, des suggestions d'amélioration ?

    La partie B est complémentaire, y a t-il un moyen d'exécuter de manière asynchrone cette fonction? J'ai vu le système de message, mais cela me semble être uniquement pour des opérations "simples". Je me trompe ?

    Un grand merci par avance

  2. #2
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 090
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 090
    Points : 8 191
    Points
    8 191
    Billets dans le blog
    17
    Par défaut
    C'est pas mal mais ça reste trop bloquant, des suggestions d'amélioration ?
    Tu veux gagner en vitesse d'insertion ? Combien de lignes à insérer ?
    Avec MySQL j'ai de bons résultats en validant une transaction tous les 500 à 3000 INSERT (il faut tester)
    ou en générant des INSERT ... VALUES (row_1), (row_2), (row_3), ...

    Mais généralement j'ai les meilleurs résultats avec LOAD DATA : https://dev.mysql.com/doc/refman/8.0/en/load-data.html


    Pour l'exécution asynchrone, il y a sûrement moyen, mais le serveur de bdd et ses verrous d'INSERT feront de toute manière goulot.
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  3. #3
    Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2020
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Avril 2020
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    40 000 à 60 000 lignes...

    Quand tu dis "validant une transaction", ça veut dire que tu utilises INSERT ... VALUES - avec 300 à 5000 row ici - c'est ça ?

    LOAD DATA - Si je comprends bien tu écris tes paramètres dans un fichier externe que tu insères ensuite dans ta DB avec LOAD DATA c'est ça ?

    Merci !

  4. #4
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 090
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 090
    Points : 8 191
    Points
    8 191
    Billets dans le blog
    17
    Par défaut
    Quand tu dis "validant une transaction", ça veut dire que tu utilises INSERT ... VALUES - avec 300 à 5000 row ici - c'est ça ?
    Non. J'ai 2 méthodes distinctes : 1. les transactions, le 2. INSERT multi-rows

    1. Les transactions

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $sql = 'INSERT INTO ta_table (col_1, col_2, col_3) VALUES (:val_1, :val_2, :val_3)';
    $insert = $pdo->prepare($sql);
    $bulk = 5_000; // Soumet la transaction toutes les $bulk lignes
    $pdo->beginTransaction();
    foreach ($data as $row_count => $record) { // Parcours des données à insérer
        $insert->execute(['val_1' => $record['val_1'], ...]); // INSERT unitaire sur requête préparée
        if ((($row_count + 1) % $bulk) === 0) {
            $pdo->commit(); // Soumission
            $pdo->beginTransaction();
        }
    }
    $pdo->commit(); // Pour le reliquat
    2. Le INSERT multi-rows

    Qui consiste à construire une requête SQL du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    INSERT INTO ta_table (col_1, col_2, col_3)
    VALUES
        (val_11, val_12, val_ 13), 
        (val_21, val_22, val_ 23), 
        (val_31, val_32, val_ 33); // Ici 3 lignes, à faire sur X milliers de lignes
    Ces 2 méthodes donnaient de bonnes perfs assez proches (mais mes tests commencent à dater sérieusement )
    Aujourd'hui, toutes les principales DB supportant les transactions, il vaut mieux utiliser la 1re méthode avec les transactions.

    LOAD DATA - Si je comprends bien tu écris tes paramètres dans un fichier externe que tu insères ensuite dans ta DB avec LOAD DATA c'est ça ?
    Oui, tu construis un fichier dans un des formats attendus par LOAD DATA (ex. TSV ou CSV).
    C'est la méthode donnant (largement) les meilleures perfs, mais il faut générer le fichier, et enfin il faut que le serveur MySQL aient les droits nécessaires pour y accéder.
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

Discussions similaires

  1. Réponses: 2
    Dernier message: 05/09/2020, 13h53
  2. Création d'une base de données pour gérer des projets
    Par Rodrigue dans le forum Modélisation
    Réponses: 4
    Dernier message: 19/11/2010, 17h14
  3. [XSLT] Comment procéder pour gérer des langues ?
    Par virgul dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 31/03/2005, 11h01
  4. Comment (si possible) gérer des dll en Asm?
    Par @drien dans le forum x86 32-bits / 64-bits
    Réponses: 5
    Dernier message: 06/01/2004, 15h59
  5. Une unité pour gérer des très grands nombres
    Par M.Dlb dans le forum Langage
    Réponses: 2
    Dernier message: 09/09/2003, 12h07

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