Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 13/10/2011, 10h21   #1
Invité régulier
 
Inscription : janvier 2005
Messages : 34
Détails du profil
Informations forums :
Inscription : janvier 2005
Messages : 34
Points : 8
Points : 8
Par défaut Ralentissement d'une requête au fur et à mesure

Bonjour à tous,

Je travail sur une petite application censée utiliser les données d'un planning prévisionnel de prospecteur/client.

Cette application doit régulièrement interroger la table de planning pour savoir si chacun des prospecteur se rend bien à ses rendez-vous.
J'ai plusieurs tables a utiliser (ces tables me sont imposées, je ne peux qu'ajouter des champs mais je ne peux ni changer leurs liaisons, ni enlever des éléments) :
planning : table des rendez-vous
prospect : table des prospecteurs (salariés)
detail_prospect : table donnant des informations complémentaires sur les prospecteurs.
client : table des clients
detail_client : table donnant des informations complémentaires sur les clients
produit : table de produits présentés

J'ai donc construit la requête suivante :
Code :
1
2
3
4
5
6
7
8
SELECT * FROM planning, prospect, detail_prospect, client, detail_client, produit
WHERE planning.id_prostect = prospect.id_prospect
AND prospect.id_dt_prospect = detail_prospect.id_dt_prospect
AND planning.id_client = client.id_client
AND client.id_dt_client = client_detail.id_dt_client
AND planning.id_produit=produit.id_produit
AND planning.pla_debut_confirme IS NULL
AND (to_char(pla_date_debut,'yyyymmdd')*10000)+(pla_hre_debut*100)+pla_min_debut >= '201110130000' AND (to_char(pla_date_debut,'yyyymmdd')*10000)+(pla_hre_debut*100)+pla_min_debut <='201110130900'
Cette requête me renvoi bien les informations souhaitées sauf que je l'exécute toutes les 5 minutes et qu'au fur et à mesure de la journée les performance se dégrade.
Il faut savoir que simultanément le planning prévisionnel évolue (ajout de rdv, suppression de rdv, modification de rdv, validation d'un RDV quand prospect confirme son arrivé chez un client).

J'avoue que je ne savais pas vraiment dans quelle catégorie poster cette demande, j'espère avoir choisi la bonne catégorie. Je ne m'y connais pas en paramétrage de base... (juste en développement)
J'ai remarqué que la commande : analyze table planning compute statistics;
Améliore le traitement mais très rapidement le traitement ralentit de nouveau...

Merci d'avance pour votre aide.
gg14bis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/10/2011, 10h51   #2
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Première question :
"Au cours de la journée, les performances se dégradent"
=> Est-ce que le lendemain, les performances sont de nouveau bonnes ?
=> Après un redémarrage de la base ?
=> Après un redémarrage de l'application cliente ?

Deuxième question :
=> La volumétrie augmente-t-elle ?
=> Dans quelles proportions ?
=> Quelle est la volumétrie actuelle ?

Troisième question :
=> Tes statistiques sont-elles à jour ?
=> Quand sont-elles recalculées ?
=> Quand tes index sont-ils reconstruit ?
=> Est-ce qu'après ces opérations de maintenance, la requête est de nouveau rapide ?

Je serais tenté de dire que s'il y a beaucoup de petits mouvements, tes statistiques sont vites faussées et tes index déséquilibrés.
Du coup Oracle patine dans la choucroute à choisir un plan d'exécution inadapté et des index contre-performants.
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/10/2011, 10h54   #3
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Essaie de faire un index organisé en cluster sur l'heure des rendez-vous plutôt que sur la clé primaire, je pense que ça évitera de déséquilibrer trop vite tes index et stats (ça évite de mélanger les informations non chronologiques, dans l'ordre de leur insertion)
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/10/2011, 10h55   #4
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 686
Points : 10 431
Points : 10 431
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
La requête en l'état sent quand même le XXième siècle.
Une bonne pratique, on ne fait jamais de select *.
On récupère uniquement les colonnes dont on a besoin.

Une autre bonne pratique, on alias les tables. Ce n'est pas obligatoire, mais ça permet de raccourcir le code d'une requête et d'en faciliter la relecture.

Toujours pour avancer, on utilise plutôt les jointures ANSI. Ça ne change rien aux performances, mais ça laisse plus de souplesse dans les jointures externes, et ça facilite aussi la relecture d'une requête en différenciant les jointures des filtres.

Enfin, le dernier filtre sur la plage, est loin d'être bien écrit !
Vous transformez des dates en texte, sur lesquels vous faites des additions et vous comparez le tout à une chaîne de caractères.

En supposant que les colonnes pla_hre_debut et pla_min_debut de la table planning soient de type numériques, on devrait pouvoir réécrire quelque chose comme ça :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT * -- pas étoile donc !
  FROM planning pla
       INNER JOIN prospect prp
         ON prp.id_prospect = pla.id_prostect -- prosTect ?
       INNER JOIN detail_prospect dpr
         ON dpr.id_dt_prospect = prp.id_dt_prospect
       INNER JOIN client cli
         ON cli.id_client = pla.id_client
       INNER JOIN detail_client dcl
         ON dcl.id_dt_client = cli.id_dt_client
       INNER JOIN produit prd
         ON prd.id_produit = pla.id_produit
 WHERE pla.pla_debut_confirme IS NULL
   AND trunc(pla.pla_date_debut, 'DD') + (pla.pla_hre_debut * 100) + pla.pla_min_debut BETWEEN trunc(sysdate, 'DD') AND trunc(sysdate, 'DD') + interval '9' hour;
À mon avis on peut encore améliorer cette dernière expression, mais là il me faut plus d'info sur les types donc, mais aussi sur les règles à appliquer.

Une dernière chose, je suis inquiet sur la modélisation de votre base, voir les id_détail dans les tables à priori mères, ça me paraît être de l'héritage un peu raté !
Pareillement sur votre table planning, vous avez trois colonnes.
Une pour la date, une pour les heures et une pour minutes, alors que toutes ces informations auraient leur place dans la première.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/10/2011, 11h31   #5
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 311
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2007
Messages : 3 311
Points : 5 813
Points : 5 813
Quelle version d’Oracle ?
Quelle volumétrie ? Quelle sont les indexes ?
Est-ce que votre requête utilise des variables de liaison (binding variables) ou des littéraux en dure comme dans votre exemple ?
Est-ce que vous pouvez tracer (trace SQL) votre traitement ?
Dans votre cas plusieurs phénomènes pourraient expliquer un ralentissement donc il faut plus des détails.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/10/2011, 12h26   #6
Membre expérimenté
 
Homme Mohamed Houri
Inscription : mars 2010
Messages : 286
Détails du profil
Informations personnelles :
Nom : Homme Mohamed Houri
Localisation : France

Informations forums :
Inscription : mars 2010
Messages : 286
Points : 563
Points : 563
Citation:
Envoyé par StringBuilder Voir le message
Essaie de faire un index organisé en cluster sur l'heure des rendez-vous plutôt que sur la clé primaire, je pense que ça évitera de déséquilibrer trop vite tes index et stats (ça évite de mélanger les informations non chronologiques, dans l'ordre de leur insertion)
Voilà une suggestion qui ne se base sur aucun fait avéré. Comment avez-vous déduit sur la base des seules informations données, c'est à dire une requête dont la performance se dégrade au fur et à mesure de l'avancement du temps d'une journée, que le problème ici est non seulement du à un déséquilibre des indexes (en passant il va bien falloir définir ce qu'est un index déséquilibré) mais également que la solution serait de faire un index organisé en cluster sur l'heure des rendez-vous plutôt que sur la clé primaire?

Je suggérerai ici de
  1. avoir l'explain plan au matin quand tout va bien
  2. avoir un autre explain plan lorsque la requête performe mal

Et analysez la différence.
__________________
Bien Cordialement
www.hourim.wordpress.com
Mohamed.Houri est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/10/2011, 13h18   #7
Membre confirmé
 
Homme Grégoire MARTIN
Ingénieur développement logiciels
Inscription : janvier 2011
Messages : 128
Détails du profil
Informations personnelles :
Nom : Homme Grégoire MARTIN
Âge : 32
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Finance

Informations forums :
Inscription : janvier 2011
Messages : 128
Points : 225
Points : 225
Bonjour,

Si il s'agit bien d'expliquer le comportement régressif d'une requête tout au long de la journée, et bien il va falloir tracer, et tracer large.

En effet des traitements batch ou une montée des transactions utilisateurs, bref une sollicitation de la base croissante peut expliquer ce phénomène.

Y a t il un comportement similaire avec d'autre requêtes qui a déjà été constaté ?

Si tu as Statspack de dispo sur ton environnement, cela pourrait déjà etre un debut pour pouvoir analyser.

http://oracle.developpez.com/guide/tuning/statpack/

http://download.oracle.com/docs/cd/B...3/statspac.htm

Sinon dans un premier temps il faudrait voir l'explain plan + volumetrie des tables + index + checker les statistiques.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT /*+ gather_plan_statistics */
   * 
  FROM planning pla
       INNER JOIN prospect prp
         ON prp.id_prospect = pla.id_prostect -- prosTect ?
       INNER JOIN detail_prospect dpr
         ON dpr.id_dt_prospect = prp.id_dt_prospect
       INNER JOIN client cli
         ON cli.id_client = pla.id_client
       INNER JOIN detail_client dcl
         ON dcl.id_dt_client = cli.id_dt_client
       INNER JOIN produit prd
         ON prd.id_produit = pla.id_produit
 WHERE pla.pla_debut_confirme IS NULL
   AND trunc(pla.pla_date_debut, 'DD') + (pla.pla_hre_debut * 100) + pla.pla_min_debut BETWEEN trunc(sysdate, 'DD') AND trunc(sysdate, 'DD') + interval '9' hour;
 
SELECT *
FROM
    TABLE (dbms_xplan.display_cursor (format=>'ALLSTATS LAST'));

PS : La dégradation peut etre chiffrée à quelle hauteur : x2,x3,xN ?
__________________
Cordialement.
ORA-007 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 04h57.


 
 
 
 
Partenaires

Hébergement Web