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

SQL Oracle Discussion :

Problème de performance avec un to_date dans where clause


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Juin 2005
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 207
    Par défaut Problème de performance avec un to_date dans where clause
    Bonjour à tous,

    J'ai un soucis de performance avec une de mes requêtes SQL.

    Cette requête exécute une recherche dans une table d'audit contenant une date de validité afin de construire une vue.

    Les données sources sont stockées dans une table:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    id       val01        end_ts
    1        1            01-JAN-2011
    2        3            03-MAR-2011
    3        5            15-AUG-2050
    4        3            15-AUG-2050
    Dans l'exemple ci-dessus, end_ts représente la date de validité.
    Les données courantes sont celles ayant end_ts = 15-AUG-2050 (une date future qui est la même pour tous les records courants - me demandez pas pourquoi cette date...), soit les records 3 & 4.

    La vue ne doit afficher que les données courantes et leur appliquer une fonction d'aggrégation (une somme).

    Afin de ne récupérer que les données courantes, je dois donc filtrer les données, ce que je fais comme cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Select sum(val01) 
    from ma_table 
    where end_ts = to_date('15-AUG-2050', 'DD-MMM-YYYY');
    Le soucis, c'est que l'utilisation de la fonction to_date réduit de manière trop importante les performances de ma requête.
    Quand j'exécute la requête sans where clause, quelques secondes suffisent.
    Par contre, avec where clause, plusieurs dizaines de minutes sont nécessaires (j'ai environ 400 000 records dans ma_table)

    Je commence donc à envisager de ne plus faire de vue, mais une seconde table, rafraichie avec une procédure SQL (qui me permettrait de stocker le résultat de to_date('15-AUG-2050', 'DD-MMM-YYYY') dans une variable, puis d'utiliser cette variable dans la where clause)

    Cependant, me gène de ne plus avoir de vue, je serais obligé de forcer un rafraichissement (job schedulé), et surtout, je me demande s'il n'y a pas de possibilité pour faire autrement!

    Merci par avance pour votre aide

  2. #2
    Membre Expert Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Par défaut
    Salut !

    Plusieurs dizaines de minutes pour 400K lignes, ça parait monstrueux...

    Par contre, to_date en soi ne ralentit pas de requêtes (essaie par exemple de faire la même sans clause where).

    Y a-t-il beaucoup de lignes courante par rapport au total des lignes ? Serait-il peut être souhaitable de poser un index sur la date ? Pourrais-tu donner le plan d'exécution de ta requête ?

  3. #3
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 953
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 953
    Par défaut
    Franchement la même que Pacmann, il faut au moins un plan (set autot trace dans sqlplus) voir un tkprof

    Sinon c'était juste pour préciser que :
    Je commence donc à envisager de ne plus faire de vue, mais une seconde table, rafraichie avec une procédure SQL (qui me permettrait de stocker le résultat de to_date('15-AUG-2050', 'DD-MMM-YYYY') dans une variable, puis d'utiliser cette variable dans la where clause)

    Cependant, me gène de ne plus avoir de vue, je serais obligé de forcer un rafraichissement (job schedulé), et surtout, je me demande s'il n'y a pas de possibilité pour faire autrement!
    Ca s'appelle une vue matérialisée (mais c'est plus pour ta culture... il n'y a aucune raison pour que la requête présentée sur 400K lignes prennent 10 minutes...)

  4. #4
    Membre confirmé
    Inscrit en
    Juin 2005
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 207
    Par défaut
    Bonjour,

    Merci pour vos réponses!

    Alors, je vais d'abord répondre à Pacman:
    Par contre, to_date en soi ne ralentit pas de requêtes (essaie par exemple de faire la même sans clause where).
    Justement, c'est exactement le problème: j'ai identifié le to_date comme facteur limitant dans ma requête, cf mon post original:
    Quand j'exécute la requête sans where clause, quelques secondes suffisent.
    Pour répondre à skuatamad:
    Merci, je sais ce qu'est une vue matérialisée (ou snapshot) . Ceci dit, je ne suis pas certains qu'on puisse utiliser une variable.

    Je m'explique: une vue matérialisée exécute une requête SQL a une fréquence donnée (tous les jours,...) Bref, je vais pas expliquer plus dans les détails.

    En gros, ma vue matérialisée va exécuter le même script que ma vue Oracle, sauf que je vais le faire à un horaire prédéfini. Ma vue matérialisée sera beaucoup plus rapide en accès, par contre, il va me falloir toujours autant de temps pour la mettre à jour...

    Par contre, si je créé une table (non matérialisée), rafraichie par un script PL/SQL, ça me semble plus efficace, mais pas très propre sur la méthode:
    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
    declare
      max_ts date := to_date('15-AUG-2050', 'DD-MON-YYYY');
    begin
      begin
        drop table mon_autre_table;
      exception
        when OTHERS then
          null;
      end;
     
      create table mon_autre_table as 
        select pt, sum(val01) 
        from ma_table 
        where end_ts = max_ts
        group by pt
      ;
    end;
    Quoiqu'il en soit, je vais poster le plan d'exécution dès demain!

  5. #5
    Membre confirmé
    Homme Profil pro
    Analyste
    Inscrit en
    Août 2003
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyste
    Secteur : Services de proximité

    Informations forums :
    Inscription : Août 2003
    Messages : 85
    Par défaut
    Bonjour,

    Et la création d'un index sur la fonction to_date(end_ts) vous l'avez peut-être déjà fait ?

  6. #6
    Membre confirmé
    Inscrit en
    Juin 2005
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 207
    Par défaut
    Citation Envoyé par startout Voir le message
    Bonjour,

    Et la création d'un index sur la fonction to_date(end_ts) vous l'avez peut-être déjà fait ?
    Bonjour,

    Je ne comprends pas votre remarque.

    La table d'origine contient la variable "end_ts", je ne vois pas comment je paux mettre un index sur "to_date(end_ts)"

    Si vous pouviez m'aider sur ce point!

Discussions similaires

  1. Réponses: 7
    Dernier message: 04/06/2006, 17h00
  2. Problème affichage form avec Internet Explorer dans un menu
    Par dupard2006 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 28/03/2006, 19h26
  3. Réponses: 8
    Dernier message: 11/02/2006, 23h36
  4. Problème de performance avec LEFT OUTER JOIN
    Par jgfa9 dans le forum Requêtes
    Réponses: 6
    Dernier message: 17/07/2005, 13h17
  5. [C#] Probléme de performance avec IsDbNull
    Par jab dans le forum Windows Forms
    Réponses: 8
    Dernier message: 04/04/2005, 11h39

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