|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 638 ![]() |
Bonjour,
La version de ma base est : Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production Alors mon schéma où j’exécute ma requête est assez petit (10Mo). Pour l'instant je vous épargne le statement sql qui ne rimerait à rien sans avoir les données. Mon problème est le suivant : J'ai créé une requête (un cube en l’occurrence) qui marche assez bien dans 95% des cas. Temps de réponse inférieur à 500ms. La requête s’exécute sur une application via le driver jdbc fournit par oracle. Mais de temps en temps, avec les même variables bindées ma requête s'emballe et utilise jusqu'à 5Go d'espace temporaire (dans le tablespace TEMP), et du coup les temps de réponse deviennent catastrophique. (sans compter l'espace temporaire utilisée qui est une aberration) J'aimerai découvrir pourquoi une telle chose survient et surtout par quel moyen puis-je analyser ça. Tout type de piste me serait utile. Merci ! Question subsidiaire, y a-t-il un moyen de visualiser des traces sql via l'interface de Enterprise management ? Ou suis-je obligé d'utiliser tkproof ? |
|
|
00
|
|
|
#2 |
![]() ![]() |
Qu'est-ce que vous appelez un cube au juste, un vrai cube OLAP créé avec Analytic Workspace Manager ou bien un modèle en étoile / flocon basé sur un modèle R-OLAP ?
Effectivement pour 10 Mo de données, 5 Go d'espace temporaire paraît surréaliste. La piste des traces me paraît la meilleure solution. Je ne sais pas si OEM permet la lecture de ces dernières, par contre vous n'êtes pas cantonné à tkprof, il y a aussi TVD$XTAT qui produit un fichier html plus "XXIème siècle", même si in fine vous y retrouverez les mêmes informations qu'avec tkprof à peu de chose près.
__________________
Email : http://scr.im/waldar |
|
10
|
|
|
#3 |
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 638 ![]() |
Bonjour,
Non ca n'est pas un vrai cube OLAP. C'est une base "standard" relationnelle où on utilise une fonction OLAP (CUBE BY en l'occurance) pour réaliser des statistiques. C'est un modèle en ..étoile si je ne m'abuse : J'ai une table centrale composée de 4 foreign key + une colonne numérique sur laquelle je fais le cube by. Cette table fait 2 Mo et à 24k d'enregistrement... J'ai indexé toutes les fk de ma base et le plan que me propose Oracle ne me semble pas "mauvais" (bien que mon interprétation puisse être mauvaise.. concernant Oracle! ) Est-ce que cela répond à votre question ? Je vais essayer de chopper ces traces et reviendrai avec. Merci |
|
|
00
|
|
|
#4 | |
![]() ![]() |
Ok, pour les modèles en étoile, les recommandations Oracle sont, dans les grandes lignes :
La documentation Oracle décrit bien la problématique (tout le chapitre sur le datawarehousing est plutôt bon) : http://download.oracle.com/docs/cd/B...s.htm#i1006335 Bon, il y a un cas de figure qui pourrait s'appliquer à votre table : Citation:
Et ça a résolu notre problème (sic). J'espère que ça fonctionne mieux en 11gR2 !
__________________
Email : http://scr.im/waldar |
|
|
10
|
|
|
#5 |
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 638 ![]() |
Merci Waldar, ce liens est intéressant mais il faut que je prenne le temps de le tester
Sinon mon plan d’exécution n'est peut-être pas si bon que ça, car j'ai des MERGE JOIN CARTESIAN qui trainent ... je vais miner dans ce sens là. |
|
|
00
|
|
|
#6 |
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 638 ![]() |
Bon, j'avance un peu mais ce que je découvre me laisse perplexe.
J'ai fait 2 traces (ci-jointe) une avec la requête qui part en live et la 2eme où c'est ok. Le plan d’exécution est différent. Ce qui change entre les deux c'est une variable. Donc pour expliquer un peu plus en profondeur ce qui est réalisé. J'ai une table de vente (T_SALE_SAL) où sont stockés des chiffres d'affaire selon certain critère. Ces critères sont en vrac : un trimestre, une activité, un account, un type de vente. C'est sur cette table là que le cube se fait (entre autres). En amont je dois sélectionner une liste d'account selon les droits de l'utilisateur afin de diminuer le nombre de lignes sélectionnables pour le cube. Dans la requête c'est la partie With .... jusqu'a V_TOT qui représente une liste d'account. Je joins ensuite cette vue V_TOT avec la table T_SALE_SAL afin de diminuer la sélectivité. Dans le cas joint, seul l'id de l'utilisateur a changé. Mais en sortie de V_TOT j'ai la même liste d'account (pour les 2 users bien qu'ils aient des droits un peu différents). Et ceci fait changer le plan d’exécution ! Aurais-je oublié de faire quelque chose au niveau des stats .. index .. autres ? Je n'ai pas encore tester votre solution Waldar, afin d'activer le star join, mais j'aimerais comprendre pourquoi l'optimiseur part en live à cet endroit |
|
|
00
|
|
|
#7 |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
En analysant les deux plans on peut constater des écarts assez important entre la cardinalité estimé et celle réelle. Vous devez investiguer pourquoi cela arrive. Vérifiez les statistiques pour T_CLUSTSEG_CLS et autres tables.
Essayez d’augmenter optimizer dynamique sampling (au moins la valeur 5) pour voir si cela aide. |
|
|
10
|
|
|
#8 | ||||
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 638 ![]() |
Bonjour,
Mes stats ont été collectés ce we. Mais par acquis de conscience je les ai relancées (j'espère que c'est comme ceci qu'il faut procéder ..) Code :
Code :
La requête qui marchait mal n'a pas changé de plan d'exécution et a le même problème. La requête qui marchait bien, a changé de plan et c'est exécutée un peu plus rapidement. je peux vous fournir les nouvelles traces si vous le souhaitez. |
||||
|
|
00
|
|
|
#9 | ||||||||||||||
![]() ![]() |
Dans la première vue, ça donne quoi si vous utilisez une variable de liaison pour le usr_id (ou alors j'ai mal compris et c'est déjà une variable de liaison) ?
Code :
Ça me paraît vraiment complexe pour un modèle en étoile : l'avantage de ces derniers étant leur facilité d'interrogation ! On peut simplifier l'écriture à quelques endroit, mais ça ne changera pas fondamentalement la requête : Code :
Code :
Code :
Code :
Code :
Code :
__________________
Email : http://scr.im/waldar |
||||||||||||||
|
10
|
|
|
#10 | |||
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 638 ![]() |
Citation:
Mais vous avez raison, pour reproduire le cas je ne l'ai pas lié. Ceci dit de cette manière j'arrive à reproduire le problème (plusieurs giga d'espace temporaire utilisée pour servir la requête). Je vais refaire des traces de la bonne manière pour voir s'il y a des changements. Citation:
Je suis obligé de faire ceci car un utilisateur peut ne pas avoir le droit de voir tous les chiffres d'affaire de tous les accounts. Il peut être associé à des profils de plusieurs niveau et chaque niveau peut englober un ou plusieurs accounts. D'où le bordel pour arriver à V_TOT. Ceci dit la base est petite et le nombre de ligne sortant de V_TOT ne dépasse pas (et ne dépassera pas) un millier de ligne. Ceci va influer sur la sélectivité de la table T_SALE_SAL qui elle pourra atteindre quelques centaines de milliers de lignes : donc si on a le maximum de ligne en sortie de V_TOT on fait un cube sur toute la table T_SALE_SAL, ou presque, et dès que l'on à moins de ligne en sortie de V_TOT le nombre de ligne de T_SALE_SAL pour le cube diminue drastiquement) Citation:
|
|||
|
|
00
|
|
|
#11 | ||||
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
D'abord voilà votre requête
Code :
La partie Code :
|
||||
|
|
10
|
|
|
#12 |
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 638 ![]() |
oui, et c'est voulu.
Dans l'idée, les sous-requêtes qui permettent de construire la requête V_TOT vont lister des account (apc_id) selon les droits de l'utilisateur. En l’occurrence, LVL_NONE est un niveau de droit administrateur, donc l'utilisateur n'aura pas de restriction. De ce fait il doit pouvoir accéder à tous les chiffres de tous les accounts. Il y a peut etre une autre solution pour arriver à mes fins. La table T_CLEARANCE_CLE permet de relier un utilisateur à n profils. Chaque profils à un "niveau" : - NON : aucune restriction (il peut tout visionner) - CLU : Niveau cluster, ceci englobe plusieurs global accounts (et donc plusieurs accounts apc_id) - ACC: niveau global account, ceci englobe plusieurs accounts - APC : niveau account, ceci englobe 1 seul account Schématiquement voici le mcd : Partie globale account (T_GSA_GSA) : T_GSA_GSA 1,1 ---- 0,n T_CLUSTSEG_CLS 1,1 --- 0,n T_CLUSTER_CLU Partie account : 1 account (T_GSA_COU_APC) est une relation entre la table global account (T_GSA_GSA) et la table des pays (T_COUNTRY_COU). Cette relation se compose donc de 2 FK sur chacune de ces tables. Partie Sale : Comme je l'ai stipulé plus haut, une sale (T_SALE_SAL) concerne 1 seul account (T_GSA_COU_APC). Donc ! un utilisateur pouvant avoir plusieurs profiles rattachés, il aura des droits de visions sur différent accounts (T_GSA_COU_APC) et ceci va directement influer sur le résultat du cube. Concernant les 2 requêtes testées : - l'utilisateur pour lequel la requete a un problème n'a qu'un seul profile de niveau administrateur (NON) - l'utilisateur pour lequel la requête fonctionne a un profile de niveau administrateur (NON) et un profile de niveau account (APC) |
|
|
00
|
|
|
#13 |
![]() ![]() |
Est-ce simplement la dernière étape de la requête qui est lente pour le second profil, ou bien est-ce une des étapes intermédiaires ?
__________________
Email : http://scr.im/waldar |
|
10
|
|
|
#14 |
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 638 ![]() |
Y a-t-il des options dans tkprof pour avoir des plans plus détaillé ? avec les temps en particulier ?
D'après ce que je comprend des plans sorties, la partie V_TOT ce fait bien (1116 apc_id distinct) et c'est après que le problème se pose. En particulier au moment où il crée une table temporaire (mais je ne sais pas à partir de quoi, ca n'est pas explicite dans le plan) pour soit préparer le cube soit joindre sur V_TOT. Je regarderai plus en profondeur à midi, et je n'ai pas encore pu essayer avec les modifs que vous avez apporté. |
|
|
00
|
|
|
#15 | |||||
![]() ![]() |
Il suffit d'exécuter la requête par bout :
Code :
Code :
Car ce qui est sûr, c'est que lors de la construction d'une de ces vues, beaucoup de lignes sont chargées dans le mauvais plan : Citation:
__________________
Email : http://scr.im/waldar |
|||||
|
10
|
|
|
#16 | ||
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
J’essayerai de réécrire la première partie ainsi
Code :
|
||
|
|
20
|
|
|
#17 | |||
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 286 ![]() |
Citation:
Code :
Bien à vous Mohamed Houri |
|||
|
|
10
|
|
|
#18 | |
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 638 ![]() |
Citation:
Bingo. Les 2 plans semblent identiques maintenant. Je vous ai joint le nouveau plan de la requête qui avait du mal. Bon bein je ne commettrai plus cette erreur d'union qui semble faire bugger un peu l'optimiseur dans le cas présent ! (de plus on gagne en nombre de jointure effectué de cette manière) Merci bien Il me restera à bien tester tous les cas de figures pour voir comment ca réagit. @Mohamed.Houri: je ne connaissais pas, je testerai edit: c'est cool, plus de problème |
|
|
|
00
|
Copyright © 2000-2012 - www.developpez.com