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

Développement SQL Server Discussion :

[Requête SQL] Optimisation de plusieurs UPDATE SET FROM


Sujet :

Développement SQL Server

  1. #1
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 73
    Points : 48
    Points
    48
    Par défaut [Requête SQL] Optimisation de plusieurs UPDATE SET FROM
    Bonjour à tous,

    Je crée une table temporaire qui va contenir tout un tas d'indicateurs. Je réalise d'abord un INSERT INTO pour créé les lignes de ma table et ensuite je réalise différents UPDATE ... SET ... FROM pour mettre à jour les différentes colonnes de ma table comme ci-dessous :

    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
     
    UPDATE	@ReturnTable
    SET	    Bon = Qte
    FROM    (SELECT	TEMP.Nom AS [RESULT_Nom], COUNT(DISTINCT TEMP.Numero) AS [Qte],  TEMP.FluxID AS [RESULT_FluxID], P.NumeroBadge
    	     FROM	@table_temporaire AS TEMP
    			INNER JOIN PASSAGES P WITH (nolock) ON P.Numero = TEMP.Numero AND P.NumeroBadge = TEMP.NumeroBadge AND P.ResultatControle = 1 AND DateHeure > @todayDate  
       	   GROUP BY	TEMP.Nom, TEMP.FluxID, P.NumeroBadge) AS [RESULT]
    WHERE Operateur = RESULT_Nom AND FluxID = RESULT_FluxID
     
    /********************************************************/			
    UPDATE	@ReturnTable
    SET	    Retours = Qte
    FROM    (SELECT	TEMP.Nom AS [RESULT_Nom], COUNT(DISTINCT TEMP.Numero) AS [Qte],  TEMP.FluxID AS [RESULT_FluxID], P.NumeroBadge
    	    FROM	@table_temporaire AS TEMP
    			INNER JOIN PASSAGES P WITH (nolock) ON P.Numero = TEMP.Numero AND P.NumeroBadge = TEMP.NumeroBadge  AND P.ResultatControle = 0	AND DateHeure > @todayDate   
          	    GROUP BY	TEMP.Nom, TEMP.FluxID, P.NumeroBadge) AS [RESULT]
    WHERE Operateur = RESULT_Nom AND FluxID = RESULT_FluxID
    J'aurais voulu savoir si il existe une syntaxe SQL me permettant de mettre à jour toutes les colonnes directement sachant que pour les différents UPDATE, les conditions dans les clause WHERE sont identiques. Quelque chose qui ressemblerait au code ci-dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    UPDATE @ReturnTable
    SET  CFBon = (SELECT ... FROM ... WHERE)
    SET  RetoursCF = (SELECT ... FROM ... WHERE)
    ...
    WHERE Operateur = RESULT_Nom AND FluxID = RESULT_FluxID
    D'avance merci pour vos réponses.

    Dens19

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    A mon avis la première solution est la plus propre.
    Dans la seconde vous allez écrire des sous requêtes avec une jointure sur la colonne de votre UPDATE, ce qui induit une jointure triangulaire, qui sera donc contre-performante.

    Pourquoi avoir utilisé une table temporaire ?

    @++

  3. #3
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 73
    Points : 48
    Points
    48
    Par défaut
    Merci de votre réponse .

    Concernant votre question,

    - Si vous voulez parler de la table @table_temporaire elle me sert à sauvegarder le résultat d'une requête que je réutilise à chaque fois dans mes UPDATE, je me suis dit que çà serait plus efficace que de réécrire la requête à chaque fois et par conséquent de la réexécuter également. Pensez-vous que c'est judicieux ? Existe-t'il une autre solution plus optimisée ?

    - Si vous voulez parler de la table @ReturnTable j'utilise une variable table car en fait ce code se trouve dans une procédure stockée, et que plusieurs clients lourds viennent récupérer le résultat de cette procédure stockée parfois simultanément mais en ayant passé des paramètres différents.
    Une table variable est donc créée à chaque fois que la procédure est appelée afin de garantir l'intégrité de mes données pour les différents clients lourds.

  4. #4
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    - Si vous voulez parler de la table @table_temporaire elle me sert à sauvegarder le résultat d'une requête que je réutilise à chaque fois dans mes UPDATE, je me suis dit que çà serait plus efficace que de réécrire la requête à chaque fois et par conséquent de la réexécuter également. Pensez-vous que c'est judicieux ? Existe-t'il une autre solution plus optimisée ?
    Le mieux reste d'écrire une requête purement ensembliste.
    Les tables temporaires, comme toute table, sont crées dans la base de données TempDB, ce qui permet de garantir leur intégrité. SQL Server se sert massivement de cette BD pour bien d'autres tâches (pour s'en convaincre il suffit de déployer la node "Tables temporaires" de cette base).
    Comme vous avez stocké vos données dans une variable table, SQL Server ne maintient pas de statistiques sur les valeurs que vous y stockez.
    Donc les performances de votre requête seront pauvres.
    A l'inverse, même si vous les stockiez dans une table #, vous obligez SQL Server à maintenir des statistiques sur des données que vous avez déjà, donc c'est aussi contre-performant.

    - Si vous voulez parler de la table @ReturnTable j'utilise une variable table car en fait ce code se trouve dans une procédure stockée, et que plusieurs clients lourds viennent récupérer le résultat de cette procédure stockée parfois simultanément mais en ayant passé des paramètres différents.
    C'est clairement impossible.
    Une application ouvre une connexion, exécute une procédure stockée, récupère le résultat s'il y a lieu, et ferme la connexion.

    Si votre application appelle de nombreuses fois la même procédure stockée avec des valeurs de paramètre différents, l'optimiseur de requête crée alors un plan de requête paramétré.
    Sachez que pour toute requête, SQL Server a besoin de statistiques pour calculer un plan optimal, et qu'avec des variables tables vos l'en empêchez.

    Si vous avez besoin de ces résultats de façon plus "pérenne", pourquoi ne pas spécifier une vue ?

    @++

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 917
    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 917
    Points : 51 693
    Points
    51 693
    Billets dans le blog
    6
    Par défaut
    Ou d'utiliser une CTE pour l'UPDATE final....

    A +

  6. #6
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 73
    Points : 48
    Points
    48
    Par défaut
    Merci de vos réponses.

    Mes connaissances en SQL sont encore limitées et je crois que ce forum va grandement m'aider .

    Pour ce qui est de l'utilisation de la table temporaire "@table_temporaire", je la supprimerai donc pour écrire une requête purement ensembliste.

    Pour ce qui est de la table "@ReturnTable", je me suis mal exprimé, en effet il s'agit de l'exécution de la procédure stockée et non pas de l'accès simultané aux résultats cette procédure en fonction d'une connexion donnée .

    Merci encore de vos réponses.

  7. #7
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 73
    Points : 48
    Points
    48
    Par défaut
    Merci de vos réponses.

    Mes connaissances en SQL sont encore limitées et je crois que ce forum va grandement m'aider .

    Pour ce qui est de l'utilisation de la table temporaire "@table_temporaire", je la supprimerai donc pour écrire une requête purement ensembliste.

    Pour ce qui est de la table "@ReturnTable", je me suis mal exprimé, en effet il s'agit de l'exécution de la procédure stockée et non pas de l'accès simultané aux résultats cette procédure en fonction d'une connexion donnée .

    Merci encore de vos réponses.

Discussions similaires

  1. requête SQL pour afficher plusieurs BD
    Par rourou25 dans le forum SQL
    Réponses: 0
    Dernier message: 28/04/2010, 19h08
  2. [Hibernate 2]Requête SQL native sur plusieurs tables
    Par Giovanny Temgoua dans le forum Hibernate
    Réponses: 0
    Dernier message: 06/04/2010, 16h10
  3. [2K5]Syntaxe Update Set From Join Group by
    Par Monstros Velu dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 15/10/2007, 10h57
  4. Réponses: 3
    Dernier message: 04/06/2007, 12h29
  5. [ASE][T-SQL] Optimisation d'un update
    Par metheorn dans le forum Sybase
    Réponses: 2
    Dernier message: 06/03/2006, 13h12

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