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 :

UPDATE et JOINTURE ? [2000]


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Chef de projets MOE/MOA
    Inscrit en
    Mars 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets MOE/MOA
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Mars 2007
    Messages : 27
    Par défaut UPDATE et JOINTURE ?
    Bonjour,

    Je possède une table POPULATION contenant ~3M enr. avec des informations diverses des individus de la population (tranches d'âge, habitude d'achats, etc.)

    J'ai dans cette table un champ me permettant de cibler mes populations en fonction de certains critères. Je génère en fonction des besoins de l'utilisateur un critère d'UPDATE de ce champ via une requête du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE POPULATION
    SET CODECIBLE = <VALEURCODE>
    WHERE SEGMENT1 = <VALEURSEGMENT1> AND SEGMENT2 = <VALEURSEGMENT2>...
    Je dois rajouter un critère de sélection spécifiant si l'individu a précédemment été contacté. Pour ce faire, je dois consulter les informations de tables CIBLE et ACTION spécifiant les périodes et actions de sollicitations menées auprès desdits individus.

    ma table ACTION (~40K enr.) contient outre la PK (ID), des dates de ciblages (DD_DEB, DD_FIN) ;
    ma table CIBLE (~36M enr.) contient outre la PK (ID), l'ID_ACTION et l'ID_INDIVIDU.

    J'hésite entre deux syntaxe pour mon update :
    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
    UPDATE POPULATION
    SET CODECIBLE = <VALEURCODE>
    WHERE EXISTS (
        SELECT * 
        FROM CIBLE INNER JOIN ACTION ON CIBLE.ID_ACTION = ACTION.ID 
        WHERE DD_DEB BETWEEN '2010-01-01' AND DATEADD(mi, 1439, '2010-02-01')
            AND DD_FIN BETWEEN '2010-01-01' AND DATEADD(mi, 1439, '2010-02-01')
            AND POPULATION.ID_INDIVIDU = CIBLE.ID_INDIVIDU
        )
     
    UPDATE POPULATION
    SET CODECIBLE = <VALEURCODE>
    WHERE 1 >= (
        SELECT COUNT(*) 
        FROM CIBLE INNER JOIN ACTION ON CIBLE.ID_ACTION = ACTION.ID 
        WHERE DD_DEB BETWEEN '2010-01-01' AND DATEADD(mi, 1439, '2010-02-01')
            AND DD_FIN BETWEEN '2010-01-01' AND DATEADD(mi, 1439, '2010-02-01')
            AND POPULATION.ID_INDIVIDU = CIBLE.ID_INDIVIDU
        )

  2. #2
    Membre averti
    Homme Profil pro
    Chef de projets MOE/MOA
    Inscrit en
    Mars 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets MOE/MOA
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Mars 2007
    Messages : 27
    Par défaut
    Bête que je suis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    UPDATE POPULATION
    SET CODECIBLE = <VALEURCODE>
    FROM CIBLE INNER JOIN ACTION ON CIBLE.ID_ACTION = ACTION.ID 
    WHERE DD_DEB BETWEEN '2010-01-01' AND DATEADD(mi, 1439, '2010-02-01')
        AND DD_FIN BETWEEN '2010-01-01' AND DATEADD(mi, 1439, '2010-02-01')
        AND POPULATION.ID_INDIVIDU = CIBLE.ID_INDIVIDU
    Validez-vous ?

  3. #3
    Membre averti
    Homme Profil pro
    Chef de projets MOE/MOA
    Inscrit en
    Mars 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets MOE/MOA
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Mars 2007
    Messages : 27
    Par défaut
    ...Suis-je bête bis, je ne peux utiliser cette option car j'utilise une procédure du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE PROCEDURE dbo.sp_update_population
        @lv_update VARCHAR(8000),
        @lv_where VARCHAR(8000)
    AS
    BEGIN
        DECLARE @lv_query nVARCHAR(4000)
     
        SET @ls_query = 'UPDATE POPULATION SET ' + @lv_update + ' WHERE ' + @lv_where
     
        EXEC sp_executesql @query = @lv_query
    END
    Cette procédure est appelée depuis mon applicatif de segmentation.

    Donc à moins d'inclure mon "FROM..." dans la clause @lv_update...

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 448
    Par défaut
    Citation Envoyé par sbouvetJD Voir le message
    ...Suis-je bête bis, je ne peux utiliser cette option car j'utilise une procédure du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE PROCEDURE dbo.sp_update_population
        @lv_update VARCHAR(8000),
        @lv_where VARCHAR(8000)
    AS
    BEGIN
        DECLARE @lv_query nVARCHAR(4000)
     
        SET @ls_query = 'UPDATE POPULATION SET ' + @lv_update + ' WHERE ' + @lv_where
     
        EXEC sp_executesql @query = @lv_query
    END
    Cette procédure est appelée depuis mon applicatif de segmentation.

    Donc à moins d'inclure mon "FROM..." dans la clause @lv_update...
    Pourquoi un query dynamique ?

    Pourquoi pas une procédure avec tous les paramètres nécessaires ?

  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
    22 002
    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 : 22 002
    Billets dans le blog
    6
    Par défaut
    Autre façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    UPDATE P
    SET    CODECIBLE = '<VALEURCODE>'
    FROM   POPULATION AS P
           INNER JOIN CIBLE  AS C 
                 ON P.ID_INDIVIDU = C.ID_INDIVIDU
           INNER JOIN ACTION AS A 
                 ON C.ID_ACTION = A.ID 
    WHERE  DD_DEB BETWEEN '2010-01-01' AND DATEADD(mi, 1439, '2010-02-01')
      AND  DD_FIN BETWEEN '2010-01-01' AND DATEADD(mi, 1439, '2010-02-01');
    Évaluez les différents plans de requête !

    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/ * * * * *

  6. #6
    Membre averti
    Homme Profil pro
    Chef de projets MOE/MOA
    Inscrit en
    Mars 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets MOE/MOA
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Mars 2007
    Messages : 27
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Autre façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    UPDATE P
    SET    CODECIBLE = '<VALEURCODE>'
    FROM   POPULATION AS P
           INNER JOIN CIBLE  AS C 
                 ON P.ID_INDIVIDU = C.ID_INDIVIDU
           INNER JOIN ACTION AS A 
                 ON C.ID_ACTION = A.ID 
    WHERE  DD_DEB BETWEEN '2010-01-01' AND DATEADD(mi, 1439, '2010-02-01')
      AND  DD_FIN BETWEEN '2010-01-01' AND DATEADD(mi, 1439, '2010-02-01');
    Évaluez les différents plans de requête !

    A +
    Comme dirait l'autre, "y a pas photo"
    Si je mets en parallèle la version "EXISTS" et cette version j'obtiens :
    "Query 1 : Query cost (relative to the batch) : 99.84%" (EXISTS)
    "Qyery 2 : Query cost (relative to the batch) : 0.16%" (INNER JOIN)

    Bon, je m'en doutais un peu

    Merci de ces réponses !

  7. #7
    Membre averti
    Homme Profil pro
    Chef de projets MOE/MOA
    Inscrit en
    Mars 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets MOE/MOA
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Mars 2007
    Messages : 27
    Par défaut
    Citation Envoyé par Sergejack Voir le message
    Pourquoi un query dynamique ?

    Pourquoi pas une procédure avec tous les paramètres nécessaires ?
    Car les paramètres sont saisis dynamiquement dans l'applicatif et la plupart sont optionnels ou à valeurs multiples

    exemple :
    SEG0 IN (1) AND SEG1 IN (2,1) AND SEG4 IN (4,2,1) AND SEG26 IN ('O9','OR') AND SEG16 IN ('FR')
    -> Clients qui ont acheté dans nos magasins, durant les 24 derniers mois et qui font en moyenne un achat par an, majoritairement de l'or et originaires de France

    Je pensais éventuellement populer une table de paramètres et opérer par jointure du type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    UPDATE POPULATION
    SET CODECIBLE = VALEURCODE
    FROM PARAMETRES_SEGMENTATION
    WHERE (POPULATION.SEG0 = PARAMETRES_SEGMENTATION.SEG0 OR PARAMETRES_SEGMENTATION.SEG0 IS NULL)
    AND POPULATION.SEG1 = PARAMETRES_SEGMENTATION.SEG1  OR PARAMETRES_SEGMENTATION.SEG1 IS NULL)
    ...
    Avec une table PARAMETRES_SEGMENTATION qui contiendrait donc une ligne par valeur possible des paramètres et une colonne par paramètre existant ?

    (Mais du coup là on parle de refonte profonde du système, ce qui ne me paraît pas improbable si la pertinence et la performance sont au rendez-vous)

  8. #8
    Membre éprouvé

    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 448
    Par défaut
    Quid de la partie dynamique par @lv_update ?

  9. #9
    Membre averti
    Homme Profil pro
    Chef de projets MOE/MOA
    Inscrit en
    Mars 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets MOE/MOA
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Mars 2007
    Messages : 27
    Par défaut
    Citation Envoyé par Sergejack Voir le message
    Quid de la partie dynamique par @lv_update ?
    La construction du CODECIBLE est conditionnée par l'applicatif en fonction du numéro de la cible à générer (l'application permet de générer 5 cibles en série).
    On aurait pu, au lieu de passer le @lv_update en paramètre (d'ailleurs je pense modifier cette partie), passer le @ci_cible et mettre du coup en "dur"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE POPULATION
    SET CODECIBLE = CASE WHEN FC_EXCLUSION = 'O' THEN '9' ELSE '0' END + CASE FC_ANNULE WHEN 'N' THEN '9' ELSE '0' END + RIGHT('0' + CONVERT(CHAR(2), @ci_cible), 2)
    WHERE ...

  10. #10
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour,

    J'hésite entre deux syntaxe pour mon update :
    A priori la première sera plus efficace : Le moteur "s’arrêtera" de chercher dès qu'il trouvera UNE ligne qui correspond à votre critère, dans la deuxième, le moteur cherchera TOUTES les lignes qui correspondent à votre critère (pour les compter).

    Plus globalement, pour comparer les performances de deux requêtes, vous pouvez les placer l'une en dessous de l'autre et afficher leur plan d’exécution : chaque plan indiquera un cout, avec un pourcentage pour ce cout par rapport au lot...

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

Discussions similaires

  1. Update et jointure
    Par poca10 dans le forum Langage SQL
    Réponses: 5
    Dernier message: 18/08/2005, 15h46
  2. Update et jointure
    Par say dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 18/07/2005, 16h29
  3. [PL/SQL] update avec jointure
    Par Fox_magic dans le forum Oracle
    Réponses: 6
    Dernier message: 09/12/2004, 12h19
  4. update et jointure
    Par frantzgac dans le forum SQL
    Réponses: 21
    Dernier message: 06/12/2004, 10h53
  5. update et jointure
    Par damn dans le forum Langage SQL
    Réponses: 8
    Dernier message: 25/02/2004, 08h44

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