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

Langage SQL Discussion :

Optimiser une procédure d'insertion


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 22
    Points : 23
    Points
    23
    Par défaut Optimiser une procédure d'insertion
    Bonjour,

    Voici ma procédure :
    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
    16
    17
    18
    19
    20
    21
    22
     
    CREATE PROCEDURE enrichi_session_instance(_count integer, _max_i integer, _max_s integer)
    LANGUAGE plpgsql
    AS $$
    BEGIN
    	_max_i = _max_i + 1;
    	FOR counter in 1.._count LOOP
    		UPDATE table1
    		SET
    			i_node = (
    				SELECT i_node
    				FROM table2
    				WHERE i_node = _max_i + counter
    			),
    			s_node = (
    				SELECT s_node
    				FROM table3
    				WHERE s_node = _max_s + counter
    			);
    	END LOOP;
    END
    $$;
    Cette procédure fonctionne sur les petites base mais la, j'ai 52 000 000 de champ. c'est la misère ...


    Explication :
    j'essaye de faire du bourrage de ma base pour grossir les tables.

    j'ai fait grossir les 2 tables "table2 & table3" par une autre procédure puis je remplie la table1 avec les valeurs nouvellement créer.
    _count , donne le nombre d'ajout à réaliser.
    _max_i , donne le dernier élément de la table2 avant l'ajout des nouvelle ligne par la procédure précédente.
    _max_s , donne le dernier élément de la table3 avant l'ajout des nouvelle ligne par la procédure précédente.


    merci d'avance pour votre aide.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    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 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Bonjour,
    Je ne vois pas de clause WHERE dans la requête de mise à jour, donc toutes les lignes de la table tgable1 sont mises à jour à chaque itération.

    Tatayo.

    P.S. tu dis que tu as 52 000 000 de champs. J'espère que tu parles de lignes, et non de colonnes.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 22
    Points : 23
    Points
    23
    Par défaut
    Ho, mince ...

    Je vais tester ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    INSERT INTO table1 ( s_node, i_node )
    values ( 
    	(select s_node from table3 WHERE s_node > _max_s LIMIT _count )
    	, (select i_node from table2 WHERE i_node > _max_i LIMIT _count ) 
    	)
    P.S. oui, je parle de lignes (Pardon).

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    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 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Sauf erreur de ma part, tu n'auras qu'une seule ligne dans la table avec cette syntaxe.
    Si tu veux faire une insertion en masse, il faut utiliser cette syntaxe:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    insert into MaTable(col1,col2)
    select colx,coly
    from AutreTable

    Tatayo

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 22
    Points : 23
    Points
    23
    Par défaut
    Citation Envoyé par tatayo Voir le message
    Sauf erreur de ma part, tu n'auras qu'une seule ligne dans la table avec cette syntaxe.
    oui, postgres refuse les listes : "ERROR: more than one row returned by a subquery used as an expression".

    Citation Envoyé par tatayo Voir le message
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    insert into MaTable(col1,col2)
    select colx,coly
    from AutreTable
    impossible, pas de "jointure" possible entre les 2 colonnes. c'est ce qui m'a fait choisir le boucle dans une procédure.

    Je vais tester ceci :
    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
     
    CREATE PROCEDURE enrichi_session_instance(_count integer, _max_i integer, _max_s integer)
    LANGUAGE plpgsql
    AS $$
    BEGIN
    	_max_i = _max_i + 1;
    	FOR counter in 1.._count LOOP
    		INSERT INTO table1 ( s_node, i_node )
    		values ( 
    			(select s_node from table3 WHERE s_node = ( _max_s + counter ) )
    			, (select i_node from table2 WHERE i_node = ( _max_i + counter ) )
    		)
    	END LOOP;
    END
    $$;

  6. #6
    Membre chevronné
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 138
    Points : 1 918
    Points
    1 918
    Par défaut
    Bonjour,

    Si tes valeurs existent tout le temps dans tes 2 tables, alors les interroger ne sert à rien dans ce cas, puisque s_node et i_node sont des valeurs calculées.
    Je ne connais pas Posgres mais dans Oracle il suffirait juste de faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    insert into table1(s_node, i_node)                     
    select _max_s + level as s_node, _max_i + level as i_node
    from dual
    connect by level <= _count

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 22
    Points : 23
    Points
    23
    Par défaut
    Citation Envoyé par vanagreg Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    insert into table1(s_node, i_node)                     
    select _max_s + level as s_node, _max_i + level as i_node
    from dual
    connect by level <= _count
    Je ne peux faire çà (je pense) vous avez remarqué que je suis pas expert.

    Mais selon ton idée, je peux faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    DO $$
    DECLARE _max_s integer := 1;
    DECLARE _max_i integer := 4;
    DECLARE _count integer := 10;
    BEGIN
    	FOR counter in 1.._count LOOP
    		INSERT INTO table1 ( s_node, i_node ) VALUES ( ( _max_s + counter ), ( _max_i + counter ) )
    	END LOOP;
    END;$$;

  8. #8
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Un INSERT INTO SELECT est très nettement plus performant qu'une boucle avec INSERT INTO VALUES.

    Sur postgresql, vous pouvez utiliser generate_series pour générer des lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    insert into table1 ( s_node, i_node ) 
    select _max_s + generate_series as s_node
         , _max_i + generate_series as i_node
      FROM generate_series(1,_count);
    Sinon plus standard avec un WITH recursif

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 22
    Points : 23
    Points
    23
    Par défaut merci à tous
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    insert into table1 ( s_node, i_node ) 
    select _max_s + generate_series as s_node , _max_i + generate_series as i_node  FROM generate_series(1,_count);
    trop simple

  10. #10
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 766
    Points : 52 563
    Points
    52 563
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    ...
    Sur postgresql, vous pouvez utiliser generate_series pour générer des lignes :
    Ou sur Microsoft SQL Server !
    https://learn.microsoft.com/fr-fr/sq...l-server-ver16

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

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

Discussions similaires

  1. création d'une procédure stockée insert
    Par minussa dans le forum Requêtes
    Réponses: 3
    Dernier message: 23/06/2011, 18h55
  2. Optimiser une procédure utilisant un curseur
    Par TizDei dans le forum Développement
    Réponses: 6
    Dernier message: 03/12/2010, 13h48
  3. optimiser une procédure stockée
    Par ed222 dans le forum Développement
    Réponses: 8
    Dernier message: 15/06/2010, 17h30
  4. [SQL2005] Optimiser une procédure stockée
    Par david_chardonnet dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 20/12/2006, 15h48
  5. Réponses: 5
    Dernier message: 09/05/2005, 12h24

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