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 :

Fonction plus lente que la requête


Sujet :

Développement SQL Server

  1. #1
    Membre actif
    Homme Profil pro
    Architecte technique
    Inscrit en
    Février 2004
    Messages
    477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 477
    Points : 223
    Points
    223
    Par défaut Fonction plus lente que la requête
    Bonjour,

    Je suis abasourdi !
    Je viens de mettre une requête dans une fonction, et qu'est ce que je constate ?
    La fonction est plus lente que ma requête.

    Une explication ?

    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
     
    SET  ANSI_NULLS ON;
    GO
    SET  QUOTED_IDENTIFIER ON;
    GO
     
    DROP FUNCTION IF EXISTS [codap_sp].[fn_get_bgc_sum]
    GO
     
    CREATE FUNCTION [xxxx].[fn_get_bgc_sum] (@iMonth INT, @iYear INT)
       RETURNS @val TABLE (bgcTot FLOAT, echeance VARCHAR (4))
    AS
    BEGIN
       DECLARE @dtStart30mn AS DATETIME
       DECLARE @dtEnd30mn AS DATETIME
       SELECT @dtStart30mn =
                 DATETIMEFROMPARTS (@iYear,
                                    @iMonth,
                                    1,
                                    0,
                                    30,
                                    0,
                                    0)
       SELECT @dtEnd30mn =
                 DATETIMEFROMPARTS (@iYear,
                                    (@iMonth + 1),
                                    1,
                                    0,
                                    0,
                                    0,
                                    0)
     
     
       INSERT INTO @val (bgcTot, echeance)
          SELECT SUM (T.bgcConsoTot) AS bgcConsoTot, T.echeance
          FROM (SELECT sum (crb.puissance_30mn) AS bgcConsoTot, crb.echeance
                FROM [xxxxx] crb
                WHERE     crb.datepoint30 BETWEEN @dtStart30mn
                                              AND @dtEnd30mn
                      AND crb.type_pt_id = 17
                GROUP BY crb.echeance
                UNION
                SELECT sum (vcrb.puissance) AS bgcConsoTot, vcrb.echeance
                FROM [xxxxx] vcrb
                WHERE     vcrb.datepoint BETWEEN @dtStart30mn
                                             AND @dtEnd30mn
                      AND vcrb.type_pt_id = 17
                GROUP BY vcrb.echeance) AS T
          GROUP BY T.echeance
     
       RETURN
    END

  2. #2
    Membre expert
    Avatar de mail.spam
    Homme Profil pro
    Développeur Windev et technicien maintenance
    Inscrit en
    Janvier 2008
    Messages
    1 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Windev et technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2008
    Messages : 1 914
    Points : 3 801
    Points
    3 801
    Par défaut
    Bonjour,

    Il y a peut être une explication dans cette discussion.
    temps-d-execution-different-entre-requete-procedure

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 897
    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 897
    Points : 53 135
    Points
    53 135
    Billets dans le blog
    6
    Par défaut
    C'est totalement logique. Une fonction c'est du code itératif. Une requêtes c'est du code ensembliste qui peut être parallélisé et utiliser un index. Les itérations ne peuvent pas utiliser d'index ni de parallélisme à cause des effets de bord.
    Conclusion : sans index et sans parallélisme, tout code itératif sera toujours beaucoup plus lent que n'importe quelle requête aussi complexe qu'elle soit.
    Un exemple que je donne souvent est la simple fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREAT FUNCTION F_DATETIME_AS_DATE(@DT DATETIME)
    RETURNS DATE
    AS
    BEGIN
       RETURN CAST(@DT AS DATE)
    END;
    Sur une table d'un million de ligne c'est la cata... Alors que le CAST(...) direct dans la requête va utiliser l'index et le parallélisme !

    La plupart des développeurs ne comprennent pas la différence entre le monde itératif qu'ils ont appris à l’école d'ingé, et le monde ensembliste des SGBD Relationnel qui fonctionne par manipulation GLOBALE d'ensemble de données et non pas en mode "ligne à ligne"...

    A +

  4. #4
    Membre actif
    Homme Profil pro
    Architecte technique
    Inscrit en
    Février 2004
    Messages
    477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2004
    Messages : 477
    Points : 223
    Points
    223
    Par défaut
    Ok. Je comprends parfaitement bien.
    Alors est ce que c'est la mème chose si je fais la même chose avec une procédure stockée ?

  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 897
    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 897
    Points : 53 135
    Points
    53 135
    Billets dans le blog
    6
    Par défaut
    Une procédure stockée permet d'encapsuler et d'enchainer différentes requêtes et procédures.... C'est tout !

    A +

Discussions similaires

  1. Sur mobile, les Data URI sont 6 fois plus lentes que les requêtes HTTP
    Par rodolphebrd dans le forum Général Conception Web
    Réponses: 0
    Dernier message: 30/07/2013, 10h32
  2. Réponses: 11
    Dernier message: 13/05/2011, 13h40
  3. Réponses: 76
    Dernier message: 29/03/2011, 16h15
  4. [Firebird][Optimisation]Plus lent que le BDE!
    Par vincentj dans le forum Débuter
    Réponses: 3
    Dernier message: 07/02/2005, 15h48
  5. DBExpress est plus lent que BDE?
    Par palassou dans le forum Bases de données
    Réponses: 4
    Dernier message: 02/07/2004, 08h39

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