|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||||
|
Membre habitué
![]() Inscription : juin 2005 Messages : 203 ![]() |
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 :
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 :
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 |
||||
|
|
00
|
|
|
#2 |
|
Membre Expert
![]() Pacman PacmanBusiness analyst Inscription : juin 2004 Messages : 1 417 ![]() |
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 ?
__________________
(c'est ma photo) Paku, Paku ! Pour les jeunes incultes : non, je ne suis pas un pokémon... Le pacblog : http://pacmann.over-blog.com/ |
|
00
|
|
|
#3 | |
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
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 : Citation:
|
|
|
|
00
|
|
|
#4 | ||||
|
Membre habitué
![]() Inscription : juin 2005 Messages : 203 ![]() |
Bonjour,
Merci pour vos réponses! Alors, je vais d'abord répondre à Pacman: Citation:
Citation:
Merci, je sais ce qu'est une vue matérialisée (ou snapshot) 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 :
|
||||
|
|
00
|
|
|
#5 |
|
Membre du Club
![]() Inscription : août 2003 Messages : 79 ![]() |
Bonjour,
Et la création d'un index sur la fonction to_date(end_ts) vous l'avez peut-être déjà fait ?
__________________
Air startout |
|
|
00
|
|
|
#6 | |
|
Membre habitué
![]() Inscription : juin 2005 Messages : 203 ![]() |
Citation:
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! |
|
|
|
00
|
|
|
#7 |
|
Membre chevronné
![]() O. JolySupport Inscription : décembre 2010 Messages : 287 ![]() |
Bonjour ?
Quels sont les plans d'exécution ? Si vous avez un index sur le champs end_ts quelle est sa taille et son type dans user_segments ? De quand datent les statistiques sur les différents objets impactés ? |
|
10
|
|
|
#8 |
|
Membre Expert
![]() Yannick Ingénieur Etudes & Developpements Inscription : février 2006 Messages : 1 125 ![]() |
A partir du moment ou vous transformez la colonne indexée dans votre clause where, vous perdrez l'utilisation des index (convert, upper, ...)
Vous devez utiliser la valeur native pour que l'index soit utilisé Bon courage
__________________
Dans la connaissance du monde, ceux qui ne savent rien en savent toujours autant que ceux qui n'en savent pas plus qu'eux. (Pierre Dac) |
|
|
01
|
|
|
#9 | ||||||||
|
Membre habitué
![]() Inscription : juin 2005 Messages : 203 ![]() |
Bonsoir à tous,
Voici la requête utilisée pour l'explain plan: Code :
Temps d'exécution de la requête: 1 min et 52 sec. Code :
Temps d'exécution de la requête: 454 msecs. Code :
Temps d'exécution de la requête: 563 msecs. Code :
|
||||||||
|
|
00
|
|
|
#10 |
|
Membre Expert
![]() Pacman PacmanBusiness analyst Inscription : juin 2004 Messages : 1 417 ![]() |
Salut,
Juste par curiosité, tu as lancé les requêtes et les explain plan avec quel outil ? Question bonus : tu parlais de "sum" au départ... pourquoi n'as tu pas cherché les plans d'exécution des requêtes "sum" ? (Et au passage tu parlais de plusieurs dizaines de minutes... mais finalement ça fait moins de 2 minutes ?) @yanika et startout : ce n'est pas sur la colonne qu'on applique une fonction ici, c'est sur une constante... donc aucun problème par rapport au potentiel index.
__________________
(c'est ma photo) Paku, Paku ! Pour les jeunes incultes : non, je ne suis pas un pokémon... Le pacblog : http://pacmann.over-blog.com/ |
|
00
|
|
|
#11 | ||||
|
Membre chevronné
![]() O. JolySupport Inscription : décembre 2010 Messages : 287 ![]() |
La requête qui pose problème est la suivante
Code :
La cardianlité estimée est de 83 740 lignes pour cette contrainte : est-ce réellement le cas ? En effet jusqu'en 11gR2 l'optimiseur n'est pas au courant affinités entre colonnes et il va donc estimer la sélectivité de n colonne comme le produit des sélectivités individuelles des colonnes. C'est une multiples raisons qui peut pousser l'optimiseur à prendre un plan d'exécution qui n'est pas optimal. On en revient donc au satistiques et aux index. Existe-t-il un index sur c.end_ts ? ou mieux sur c.id et c.end_ts ? Quelles sont les statistiques de la table, des index et des colonnes ? Quand et comment ont-elles été calculées ? Et surtout reflètent-elles suffisamment la réalité ? Que se passe-t-il si la requête est réécrite comme suit Code :
|
||||
|
00
|
|
|
#12 |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
Les données provient des tables a et c seulement. Les filtre sont posées sur la table a la table b et la table c. Le filtre sur la table a est très fort, valeur unique de la clé primaire (a.id = 1). Le filtre sur la table b est très peu sélective (col = ‘Y’). Le filtre sur la table c (date = 15-08-3051) utilise une date bidon pour remplacer un null et a pour conséquence d’introduire une non-uniformité des données très forte. Sans histogrammes sur cette colonne l’optimiseur part tranquillement dans les choux.
La requête qui n’utilise pas de date ne peut se baser que sur le filtre de la table b et le plan attaque cette table en full. La requête qui utilise sysdate implique le même plan due à la forte non-uniformité des données de la collone c.end_ts autrement dit il est plus intéressant de commencer avec la table b que avec la table c Bref, je n’ai pas vu de version de base Oracle mais je pense que c’est une base Oracle 9. Il est très probable que recalculer les statistiques avec génération des histogrammes là où besoin est devrait améliorer les choses. |
|
|
00
|
|
|
#13 | |||||
|
Membre habitué
![]() Inscription : juin 2005 Messages : 203 ![]() |
Citation:
Citation:
Citation:
Les stats de la table sont mises à jour tous les jours. Je ne sais pas quelles sont les informations dont vous avez besoin, mais je peux déjà vous donner ça: AVG_ROW_LEN 76 AVG_SPACE 1455 AVG_SPACE_FREELIST_BLOCKS 0 BACKED_UP N BLOCKS 697 312 BUFFER_POOL DEFAULT CACHE N CHAIN_CNT 4 985 CLUSTER_NAME CLUSTER_OWNER COMPRESSION DISABLED DEGREE 1 DEPENDENCIES DISABLED DURATION EMPTY_BLOCKS 91 FREELISTS FREELIST_GROUPS GLOBAL_STATS YES INITIAL_EXTENT 80 Kb INI_TRANS 1 INSTANCES 1 IOT_NAME IOT_TYPE LAST_ANALYZED 05/16/11 20:55:54 LOGGING YES MAX_EXTENTS 2 147 483 645 MAX_TRANS 255 MIN_EXTENTS 1 MONITORING NO NESTED NO NEXT_EXTENT NUM_FREELIST_BLOCKS 0 NUM_ROWS 137 122 804 OBJECT_ID_TYPE OWNER RXC PARTITIONED NO PCT_FREE 10 PCT_INCREASE PCT_USED ROW_MOVEMENT DISABLED SAMPLE_SIZE 34 280 701 SECONDARY N SKIP_CORRUPT DISABLED TABLESPACE_NAME RXC_RESP_TSPA TABLE_LOCK ENABLED TABLE_NAME RESPONSES TABLE_TYPE TABLE_TYPE_OWNER TEMPORARY N USER_STATS NO Citation:
Citation:
|
|||||
|
|
00
|
|
|
#14 | ||||||||
|
Membre chevronné
![]() O. JolySupport Inscription : décembre 2010 Messages : 287 ![]() |
ok, on la refait doucement
Pour obtenir les statistiques sur les tables : Code :
Code :
Pour obtenir les obtenir les statistiques sur les colonnes impactées Code :
Code :
|
||||||||
|
00
|
|
|
#15 | |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
Citation:
Le filtre sur la table c (date = 15-08-3051) utilise une date dans le futur pour remplacer un null et a pour conséquence d’introduire une non-uniformité des données très forte. Sans histogrammes sur cette colonne l’optimiseur part tranquillement dans les choux. Voilà, maintenant relisez. |
|
|
|
00
|
Copyright © 2000-2012 - www.developpez.com