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 :

[OPTIMISATION] Date en tant que variable dans les clauses WHERE


Sujet :

Développement SQL Server

  1. #1
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 73
    Par défaut [OPTIMISATION] Date en tant que variable dans les clauses WHERE
    Bonjour,

    Depuis quelques jours j'essaye d'optimiser des procédures stockées d'une base SQL SERVER 2000, et je m'aperçois que certaines utilisent des variables date comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DECLARE @DateDuJour AS DATETIME
    SET @DateDuJour = cast(convert(varchar, GETDATE(),3) as datetime)
    Puis cette variable est réutilisée dans le reste de la procédure comme par ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT ...
    FROM...
    WHERE DateReception > @DateDuJour
    Or en ayant fait des essais sur une base de test, ou je remplaçais @DateDuJour par une date rentrée manuellement ex : '09/09/09 00:00:00', les requêtes étaient moins gourmandes en ressources. J'ai donc essayé de remplacé la variable par son expression directement dans mes requêtes comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT ...
    FROM...
    WHERE DateReception > cast(convert(varchar, GETDATE(),3) as datetime)
    Et effectivement après avoir relancé les procédures concernées, celles-ci ont demandé moins de ressources au serveur (Duration et Read inférieurs sur le profiler).

    Ce gain est appréciable mais je n'arrive pas à comprendre ce phénomène, quelqu'un aurait-il une explication ?

    Merci d'avance pour vos réponses.

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 017
    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 017
    Billets dans le blog
    6
    Par défaut
    Quel est le type de données de la colonne DateReception ? Datetime ou CHAR ???

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

  3. #3
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 73
    Par défaut
    Bonjour,

    il s'agit bien de champs DATETIME dans les tables concernées.

    Cdlt.

  4. #4
    Expert confirmé
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Par défaut
    Bonjour,

    Quelle version de SQL Server utilisez vous ?

    ++

  5. #5
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 73
    Par défaut
    je travaille sur des bases SQL SERVER 2000 SP3

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select @@VERSION
    --Microsoft SQL Server  2000 - 8.00.760 (Intel X86)   Dec 17 2002 14:22:05   Copyright (c) 1988-2003 Microsoft Corporation  Enterprise Edition on Windows NT 5.0 (Build 2195: Service Pack 4) 

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 017
    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 017
    Billets dans le blog
    6
    Par défaut
    Sachant donc que DateReception est de type DATETIME, il n'y a aucun intérêt, si ce n'est un certains masochisme de caster une date en char puis de la recaster en date !!!! Ce qui est fait ici :

    DateReception > cast(convert(varchar, GETDATE(),3) AS datetime)

    Il serait plus intelligent d'écire :

    DateReception > GETDATE()
    Tout simplement.

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

  7. #7
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 73
    Par défaut
    Je vous assure n'être aucunement masochiste !!!! Je n'ai peut être pas été assez précis dans mon énoncé, ce qui vous induit certainement en erreur. En effet ce code permet de faire des extractions pour la date du jour, par exemple combien de produits ont été reçus depuis ce matin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DateReception > cast(convert(varchar, GETDATE(),3) AS datetime) 
    -- Equivalent de : DateReception > '15/09/2009 00:00:00'
    L'utilisation du code que vous proposez ne me retournera aucun résultat car il prend en compte l'heure actuelle (Equivalent de DateReception > '15/09/2009 13:58:00') :
    Il serait plus intelligent d'écire :

    Citation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DateReception > GETDATE()

    Je vais quand même essayer de continuer à comprendre pourquoi dans certains cas il est préférable d'utiliser l'expression d'une date directement dans la clause WHERE plutôt qu'en passant par une variable.

    A+

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 128
    Par défaut
    Bonjour,

    Je peux vous donner un cas dans lequel il est obligatoire de passer par une variable plutôt que par l'expression elle-même.

    Lorsque vous utilisez une sous-requête définie dans une fonction, vous ne pouvez pas utiliser GETDATE comme critère de cette sous-requête. Si vous avez besoin de ce critère, vous devez passer cette date en paramètre à la fonction.

    L'utilisation d'une variable dans une PS peut s'expliquer si elle a été écrite par quelqu'un qui s'est dit que si ça plante dans une fonction, ça va planter aussi dans une PS...

  9. #9
    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 : 44
    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
    Par défaut
    Passez donc par une date au format ISO :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT CONVERT(CHAR(8), GETDATE(), 112)
    ou encore :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME)
    @++

  10. #10
    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
    Si DateReception est aussi une date où l'heure (mm, ss, ..) sont à 0, tu peux faire la comparaison :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DateReception >= DATEADD(dd, -1, GETDATE())

  11. #11
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 73
    Par défaut
    Bonjour à tous,

    Merci pour vos réponses.

    @Sergejack
    DateReception est aussi une date où l'heure (mm, ss, ..) sont à 0
    Malheureusement ce n'est pas le cas dans DateReception sont stockées les dates et heures réelles de réceptions.

    @Elsuket
    Passez donc par une date au format ISO
    Je vous remercie je vais essayer de passer toutes mes requêtes impliquant des dates au format ISO.

    Je continue par rapport au sujet initiale de ce poste et voici ce que j'observe avec les requêtes suivantes en analysant leur plan d'exécution :
    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
     
    SELECT Numero, DateDeballage
    FROM INTER
    WHERE DateDeballage >  CONVERT(CHAR(8), GETDATE(), 112)
    -- Coût de la requête 0%
    GO
    SELECT Numero, DateDeballage
    FROM INTER
    WHERE DateDeballage > CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME)
    -- Coût de la requête 25%
    GO
    SELECT Numero, DateDeballage
    FROM INTERV
    WHERE DateDeballage > cast(convert(varchar, GETDATE(),3) AS datetime)
    -- Coût de la requête 0%
    GO
    DECLARE @Date1 AS DATETIME;
    SELECT @Date1 = CONVERT(CHAR(8), GETDATE(), 112)
    SELECT Numero, DateDeballage
    FROM INTER
    WHERE DateDeballage >  @Date1
    -- Coût de la requête 25%
    GO
    DECLARE @Date2 AS DATETIME;
    SELECT @Date2 = CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME)
    SELECT Numero, DateDeballage
    FROM INTER
    WHERE DateDeballage > @Date2
    -- Coût de la requête 25%
    GO
    DECLARE @Date3 AS DATETIME;
    SELECT @Date3 = cast(convert(varchar, GETDATE(),3) AS datetime)
    SELECT Numero, DateDeballage
    FROM INTER
    WHERE DateDeballage > @Date3
    -- Coût de la requête 25%
    Avec DateDeballage de type DATETIME, Numero de type INT.

    Je ne comprend pas ces différences sur les plans d'executions de ces requêtes !!!!

    A+

  12. #12
    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 : 44
    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
    Par défaut
    Nous ne pourrons vous aider que si nous disposons des plans de requête ...
    Sans eux il est impossible d'aller plus loin ...

    @++

Discussions similaires

  1. Problème de variable dans la clause WHERE avec CONVERT + DATE
    Par Archi89 dans le forum Développement
    Réponses: 4
    Dernier message: 09/01/2015, 21h35
  2. variables dans la clause where
    Par ledisciple dans le forum Langage SQL
    Réponses: 8
    Dernier message: 07/08/2009, 16h17
  3. [AC-2000] Déclarer une procédure en tant que variable dans une procédure globale
    Par kir4000 dans le forum VBA Access
    Réponses: 1
    Dernier message: 04/08/2009, 17h52
  4. Réponses: 7
    Dernier message: 29/04/2009, 00h26
  5. Réponses: 2
    Dernier message: 16/04/2008, 21h06

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