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 :

Optimiser le temps d'execution d'une requete avec plusieurs tables


Sujet :

Développement SQL Server

  1. #1
    Membre régulier Avatar de dany13
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 100
    Points
    100
    Par défaut Optimiser le temps d'execution d'une requete avec plusieurs tables
    Bonjour,

    j'ai un soucis (qui est souvent récurrent à vrai dire), concernant l'optimisation du temps d'exécution des requêtes complexes car impliquant multi-jointures et tables.

    J'ai une requête qui joint pas moins de 11 tables (et toutes sont nécessaires!)
    Si je laisse tel que ma requête et mes jointures dans le code de ma procédure stockée, mon applicatif prend un certain temps à afficher les données.

    1ère proposition : j'ai pensé alors mettre cette requête dans une vue et ainsi appeler la vue dans ma procédure stockée mais je ne sais pas si j'y gagnerai ou pas?

    2ème proposition : mettre ma requête dans une vue, copier le contenu de la vue dans une table. Utiliser cette table dans ma procédure stockée. Et pour mettre a jour cette table, mettre en place une tache (si ça existe) qui copie le contenu de la vue dans la table (genre tous les jours ou 2X/jours). Et ainsi j'utilise cette table, au lieu de la requête, dans ma procédure stockée. Y gagnerai-je ou pas?

    Y a t'il d'autres moyens plus efficace?

    Merci de votre aide
    Carpe Diem : Profitez du moment présent
    La connaissance non partagée n'a pas vraiment son utilité

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Votre seconde proposition existe "nativement" depuis SQL Server 2005 et s'appelle une vue indexée :
    http://technet.microsoft.com/en-us/l.../cc917715.aspx

  3. #3
    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
    Points : 1 234
    Points
    1 234
    Par défaut
    Tu devrais peut-être simplement étudier la possibilité de créer/changer certains index sur tes tables.
    Most Valued Pas mvp

  4. #4
    Membre régulier Avatar de dany13
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 100
    Points
    100
    Par défaut
    Sergejack, j'ai pensé effectivement à mettre certains index sur les tables, mais elles sont si volumineuses et nombreuses que je n'ai aucune idée sur l'efficacité que ça pourrait avoir.

    Waldar, je ne connaissais pas cette possible! J'ai déjà créer des vues auparavant mais pas indexées. Comment "rajoute t'on" cette notion? Pour la création, je passe par l'IHM. Est ce possible par ce biais ou faut-il que j'intègre cette dimension à l'aide d'un script? Avez-vous un exemple?

    Merci par avance
    Carpe Diem : Profitez du moment présent
    La connaissance non partagée n'a pas vraiment son utilité

  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 782
    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 782
    Points : 52 783
    Points
    52 783
    Billets dans le blog
    5
    Par défaut
    Avant cela (création d'une vue indexée) commencez par poster intégralement :
    1) la requête
    2) la description sous forme DML de vos tables avec tous les index...

    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 régulier Avatar de dany13
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 100
    Points
    100
    Par défaut
    Bonjour,
    Concernant les indexes, je ne maitrise pas assez la chose pour en mettre en place, d'autant plus que je ne sais pas s'il en existe déjà...
    C'est pour cela que la solution des vues indexes me parait "moins dangereuse" si ça peut répondre au problème de la même façon.

    Je suis quasiment au bout mais je rencontre le soucis suivant :
    Ma 1ère vue contient ces éléments suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    VIEW_EDITIONS
    ----------------
    ID_EDITEURS
    ID_AUTEURS
    REFERENCES
    PUBLICATIONS
    Ma 2ème vue contient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    VIEW_AUTEURS
    ----------------
    ID_EDITEURS
    ID_AUTEURS
    EST_CLASSIQUE
    EST_HUMOURISTIQUE
    EST_POPULAIRE
    DETAILS
    DATE
    Je souhaiterai faire une vue qui me permettrai de compléter la première avec 3 champs "flag":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    VIEW_INTERMEDIAIRE
    ---------------------
    ID_EDITEURS
    ID_AUTEURS
    REFERENCES
    PUBLICATIONS
    EDITEUR_CLASSIQUE
    EDITEUR_HUMOURISTIQUE
    EDITEUR_POPULAIRE
    Je pensais faire le traitement suivant mais je ne m'en sors pas!!
    Dans la vue VIEW_AUTEURS on a effectivement les infos qui nous permettent de completer les 3 flag de VIEW_INTERMEDIAIRE, exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ID_ED | ID_AUT | EST_CLASS |EST_HUM | EST_POP |DETAILS |DATE
    1         1            1           0       0             xxxx       12/10/1980
    1         2            0           1       0             xxxx       12/10/1990
    1         3            1           0       0             xxxx       12/10/1995
    1         3            1           1       0             xxxx       12/10/1995
    On aurait donc dans la vue VIEW_INTERMEDIAIRE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ID_ED |ID_AUT|REF|EDITEUR_CLASS|EDITEUR_HUM|EDITEUR_POP
    1         1           ##   1          0                  0
    1         2           ##   0          1                  0
    1         3           ##   1          1                  0
    Comment puis je faire?
    j'ai essayé de passer par une fonction scalaire qui me remplirait donc mes flag du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    ALTER FUNCTION [dbo].[FN_AUTEURS] (@ID_AUTEUR int) 
    	RETURNS int
    AS
    BEGIN 
    	DECLARE @ID_AUTEUR int
    	SET @ID_AUTEUR = 0
    Select @EDITEUR_CLASS = MAX(Case When (EST_CLASSIQUE = 0 or EST_CLASSIQUE = 'false' ) Then 0 Else 1 End) 
    	From VIEW_AUTEURS
    			JOIN VIEW_EDITIONS
    			ON VIEW_AUTEURS.ID_AUTEURS = VIEW_EDITIONS.ID_AUTEURS
    	Where VIEW_AUTEURS.ID_AUTEURS =@ID_AUTEUR
    RETURN @EDITEUR_CLASS
    END
    Mais bon ça ne fonctionne pas...
    Je suis desèspérée...
    HELPPPPPPPPPPPPPP!

    Merci par avance!
    ++
    Carpe Diem : Profitez du moment présent
    La connaissance non partagée n'a pas vraiment son utilité

  7. #7
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Salut,

    C'est quoi le "ID_EDITEURS" dans "VIEW_AUTEURS" ?

    Pourquoi utiliser une fonction pour faire ça ?

    Comment tu différencies les deux dernières lignes dans ton exemple de "VIEW_AUTEURS" ? (pour moi, la vue a décidément un sérieux problème de conception/cohérence)

    Cette requête ne marche pas ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select a.id_auteurs, max(e.editeur_classique) est_classique, max(e.editeur_humoriste) est_humoriste, max(e.editeur_populaire) est_populaire
    from view_auteurs a
    inner join view_editions e on e.id_auteurs = a.id_auteurs
    -- where a.id_auteur = @id_auteur
    group by a.id_auteur
    => Ensuite, tu peux rajouter une jointure sur VIEW_EDITIONS si t'as vraiment besoin de mélanger les informations, mais pour moi t'es en train de faire une belle potée auvergnate...


    Sinon, ta fonction corrigée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    ALTER FUNCTION [dbo].[FN_EST_CLASSIQUE] (@ID_AUTEUR int) 
    	RETURNS int
    AS
    BEGIN 
    	DECLARE @ID_AUTEUR_RES int
    	SET @ID_AUTEUR_RES = 0
    SELECT @ID_AUTEUR_RES = MAX(EDITEUR_CLASSIQUE) 
    	FROM VIEW_EDITIONS
    	WHERE ID_AUTEURS =@ID_AUTEUR
    RETURN @ID_AUTEUR_RES
    END
    Tout du moins, c'est ce que j'en comprends...
    On ne jouit bien que de ce qu’on partage.

  8. #8
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 782
    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 782
    Points : 52 783
    Points
    52 783
    Billets dans le blog
    5
    Par défaut
    Plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    ALTER FUNCTION [dbo].[FN_EST_CLASSIQUE] (@ID_AUTEUR int) 
    	RETURNS int
    AS
    BEGIN 
     
    RETURN COALESCE(SELECT MAX(EDITEUR_CLASSIQUE) 
    	FROM VIEW_EDITIONS
    	WHERE ID_AUTEURS =@ID_AUTEUR), 0)
     
    END
    En définitive, et comme vous pouvez le constater il ne sert àrien de faire une telle fonction, car c'est juste un sous requête. Or en faisant une fonction vous vous interdisez l'utilisation des index, alors qu'avec une sous requête c'est possible !

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

  9. #9
    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
    Points : 1 234
    Points
    1 234
    Par défaut
    Moralité : vous pourriez créer une view.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CREATE VIEW dbo.vFN_EST_CLASSIQUE
    AS
    SELECT
    	ISNULL(MAX(EDITEUR_CLASSIQUE) , 0)
    	, VIEW_AUTEURS.ID_AUTEURS
    FROM VIEW_AUTEURS
    LEFT JOIN VIEW_EDITIONS ON (
    	VIEW_EDITIONS.ID_AUTEURS = VIEW_AUTEURS.ID_AUTEURS
    )
    GROUP BY VIEW_AUTEURS.ID_AUTEURS
    Most Valued Pas mvp

  10. #10
    Membre régulier Avatar de dany13
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 100
    Points
    100
    Par défaut
    Bonsoir,

    Merci pour vos réponses et votre précieuse aide. J'ai tout essayé :
    - modification de la fonction d'après @StringBuilder et @SQLpro
    - création de la vue à partir des éléments de @Sergejack

    Malheureusement ça ne s'adapte pas à mon cas, étant donnée qu'il y a trop de tables, de jointures et de traitements-valeurs à remonter (les flags) qui sont très gourmandes en ressources

    De plus, je ne suis malheureusement pas assez calée en "indexation" pour les utiliser au mieux En revanche, si vous avez des liens, sites, docs d'info sur le sujet, je prends!

    La solution que j'ai adopté et qui fonctionne à merveille est de passer par la création de 2 vues, de 2 tables et d'une procédure stockée, qui indexe les 2 tables à partir des 2 vues, que je lance de manière automatique par une tache planifiée. Mes temps de réponse sont très court, c'est hallucinant!

    Merci infiniment pour vos réponses, j'ai pu expérimenter tout de même certaines choses que je ne connaissais pas jusqu'alors

    @bientôt
    Carpe Diem : Profitez du moment présent
    La connaissance non partagée n'a pas vraiment son utilité

  11. #11
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 7
    Points : 10
    Points
    10
    Par défaut
    Le "Database Engine Tuning Advisor" est généralement de bon conseil pour les indexs lorsqu'il est employé en conjonction avec le "SQL Server Profiler" ;-)

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

Discussions similaires

  1. Temps d'execution d'une requete
    Par toto2233 dans le forum Requêtes
    Réponses: 8
    Dernier message: 19/07/2007, 08h55
  2. Réf : Mesurer le temps d 'execution d 'une requete
    Par akrabmehdi dans le forum SQL
    Réponses: 1
    Dernier message: 10/07/2007, 20h48
  3. temp d'execution d'une requete sql
    Par mitoubra dans le forum JDBC
    Réponses: 4
    Dernier message: 15/06/2007, 22h34
  4. [Stratégie] Mesurer le temps d'exécution d'une requête
    Par nice dans le forum Général Java
    Réponses: 5
    Dernier message: 29/01/2006, 17h53
  5. Réponses: 9
    Dernier message: 20/06/2005, 12h17

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