1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    mars 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mars 2012
    Messages : 3
    Points : 1
    Points
    1

    Par défaut Comment optimiser un insert en masse à partir d'une table volumineuse

    bonjour à tous ,

    j'ai une table "table_src" avec des index qui fait + 40 millions de lignes et je dois modifier la structure de la table en ajoutant des colonnes.
    j'ai de gros problèmes de performance ça met 4 heures et ça plante car je rencontre des problèmes d'espace disque avec la base tempdb

    version sql = sql server 2008 R2 , la mémoire allouée à sql est de 2 Go et il reste 20 Go sur le serveur

    voici ce que j'ai fait :
    - la base est en mode simple
    - j'ai créé une nouvelle table table_dest avec la nouvelle structure avec la clé primaire

    SET NOCOUNT ON
    insert into dbo.table_dest (...) select .... from dbo.table_src

    - après l'insert j'ai créé les index sur la table table_dest.

    je ne sais pas si par exemple il est préférable de créer les index sur la table finale avant ou après l'insert
    j'aurai voulu faire un test en faisant des insertions par bloc pour maîtriser la taille de la base tempdb mais je ne sais pas comment faire.
    au final je ne sais pas trop comment m'y prendre , à part sinon de demander à l'infra d'augmenter la mémoire et l'espace disque du serveur mais ça va prendre des semaines.


    merci d'avance pour aide

  2. #2
    Rédacteur
    Avatar de SQLpro
    Homme Profil pro
    Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Inscrit en
    mai 2002
    Messages
    16 439
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 16 439
    Points : 38 136
    Points
    38 136

    Par défaut

    Avec si peu de ram vous n'arriverez jamais. Les sgbdr traitant les données en mémoire il faut que l'intégralité des données de la table puise figurer en mémoire ainsi que la journalisation ... Commencez par mettre au moins 16 go de ramener à votre serveur et vous verrez que vous allez résoudre tous les problèmes : vitesse, temps et crash...
    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...
    * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    mars 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mars 2012
    Messages : 3
    Points : 1
    Points
    1

    Par défaut

    merci pour votre réponse , j'ai déjà fait la demande à notre infra pour avoir plus de mémoire...
    mais avant que ça soit fait ça va prendre du temps
    j'essaye de trouver une solution en parallèle

  4. #4
    Rédacteur
    Avatar de SQLpro
    Homme Profil pro
    Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Inscrit en
    mai 2002
    Messages
    16 439
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 16 439
    Points : 38 136
    Points
    38 136

    Par défaut

    alors il faut le en splittant la table.

    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...
    * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    mars 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mars 2012
    Messages : 3
    Points : 1
    Points
    1

    Par défaut

    je suis parti sur cette idée

    merci pour votre aide

  6. #6
    Modérateur
    Avatar de elsuket
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    janvier 2005
    Messages
    5 662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : janvier 2005
    Messages : 5 662
    Points : 11 540
    Points
    11 540

    Par défaut

    Bonjour,

    Effectivement avec 2Go cela va être difficile. Une fois que vous aurez plus de RAM, les performances (outre cet INSERT) s'en ressentiront immédiatement : les applications qui accèdent à la base de données vont "respirer"

    Vous pouvez procéder au peuplement de la nouvelle table par les lignes de l'ancienne en copiant les lignes par lots de 10 000, par exemple :

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    -- Extraction des valeurs de clé primaire subrogée de la table source
    SELECT	id
    INTO	dbo.table_auxiliaire
    FROM	dbo.table_source
     
    -- Ceci crée implicitement un index cluster
    -- qui va bien supporter les ORDER BY qui suivent
    ALTER TABLE dbo.table_auxiliaire
    ADD CONSTRAINT PK_table_auxiliaire PRIMARY KEY(id)
     
    ------------------------------------------------------------
     
    DECLARE @i int = 0
    	, @dt datetime
    	, @msg varchar(1024)
     
    WHILE EXISTS
    (
    	SELECT	*
    	FROM	dbo.table_auxiliaire
    )
    BEGIN
    	SELECT	@i += 1
    		, @dt = GETDATE();
     
    	-- On copie les 10000 lignes suivantes dans la table cible ...
    	WITH
    		CTE AS
    		(
    			SELECT	TOP 10000 id
    			FROM	dbo.table_auxiliaire
    			ORDER	BY id
    		)
    	INSERT INTO dbo.table_cible
    	(
    		id
    		, les_autres_colonnes
    	)
    	SELECT		S.id
    			, S.les_autres_colonnes
    	FROM		CTE AS C
    	INNER JOIN	dbo.table_source AS S
    				ON C.id = S.id;
     
    	-- ... une fois qu'elles sont traitées, on peut les supprimer de la table auxiliaire
    	WITH
    		CTE AS
    		(
    			SELECT	TOP 10000 id
    			FROM	dbo.table_auxiliaire
    			ORDER	BY id
    		)
    	DELETE FROM	dbo.table_auxiliaire
    	FROM		CTE AS C
    	INNER JOIN	dbo.table_auxiliaire AS A
    				ON C.id = A.id;
     
    	-- Sortie dans la console (Onglet Messages de SQL Server Management Studio)
    	SET @msg = 'Batch #' + CAST(@i AS varchar(10)) + '	 -	' + CAST(DATEDIFF(millisecond, @dt, GETDATE()) AS varchar(20));
    	RAISERROR(@msg, 0, 1) WITH NOWAIT;
    END
    Et pour suivre le déplacement des lignes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT		S.name + '.' + T.name AS table_name
    		, PS.row_count
    FROM		sys.dm_db_partition_stats AS PS
    INNER JOIN	sys.tables AS T
    			ON T.object_id = PS.object_id
    INNER JOIN	sys.schemas AS S
    			ON S.schema_id = T.schema_id
    WHERE		S.name = 'dbo'
    AND		T.name IN
    		(
    			'table_source'
    			, 'table_cible'
    			, 'table_auxiliaire'
    		)
    Il est préférable de créer les index une fois que la nouvelle table est complètement peuplée.

    @++

Discussions similaires

  1. Réponses: 5
    Dernier message: 29/07/2016, 23h06
  2. Réponses: 7
    Dernier message: 04/08/2009, 16h29
  3. [Conception] Menu deroulant à partir d'une table volumineuse
    Par newbycool dans le forum Modélisation
    Réponses: 15
    Dernier message: 20/04/2007, 12h26
  4. Comment faire pour générer un fichier à partir d'une BD MySQL
    Par dessinateurttuyen dans le forum Requêtes
    Réponses: 2
    Dernier message: 06/07/2006, 21h39
  5. comment creer un treeview a partir d une table
    Par steeves5 dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 28/06/2006, 19h03

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