Oracle et les index

Oracle et les index - SQL/NoSQL - Programmation

Marsh Posté le 16-06-2008 à 11:40:11    

Bonjour,
 
J'ai de gros soucis sur les temps d'accès à une bd oracle, et plus particulièrement lors d'une insertion.
J'ai déjà mis plusieurs index, mais ça ne change pas, à tel point que pour faire une insertion, cela prends 6 minutes.
L'insertion en question récupère des infos de 2 tables :
CURSOR calendrier IS
 SELECT c.annee, c.jour,h.arrivee, h.depart,h.depart-h.arrivee  
   FROM psu.calendrier c,psu.horcontrat h
  WHERE c.fermeture='O'
    AND c.jour BETWEEN :contrat.debut AND :contrat.fin
    AND c.type=:contrat.type
    AND c.code=:contrat.code
    AND h.jour = c.jour-(indice*:contrat.cycle)  
    AND h.matricule=:enfant.matricule
    AND h.num_ordre=:enfant.num_ordre
    AND h.type=:contrat.type
    AND h.code=:contrat.code;
Ces 2 tables ne font pas plus de 5000 lignes, donc selon moi, pas besoin d'index.
Par contre après, je fais l'insertion dans la table horprev qui contient déjà 140.000 lignes.
INSERT INTO psu.horprev (type,code,annee,matricule,num_ordre,jour,arrivee,depart,
                                    numero)
 VALUES (:contrat.type,:contrat.code,annee,:enfant.matricule,:enfant.num_ordre,
                jour_cal,horarrivee,hordepart,section);
Et à mon avis c'est là que ça bloque.
J'ai déjà mis 3 index sur horprev, mais est ce que cela ne ralentirai pas l'accès ?
Merci de votre aide !

Reply

Marsh Posté le 16-06-2008 à 11:40:11   

Reply

Marsh Posté le 16-06-2008 à 11:54:30    

5000 lignes ça vaut le coup de mettre un index, au vu de ta requête si contrat.code est bien le numéro de contrat il y a pas mal de chance pour qu'il soit unique ou pas loin de l'être, donc tu devrais avoir un index dessus sur tes deux tables.
 
et le mieux pour être sur que c'est ça qui ralentit ou pas çà reste encore de sortir le plan d'exécution; perso je commencerai par la

Reply

Marsh Posté le 16-06-2008 à 11:54:56    

dans la plupart des cas, les indexes permettent une recherche rapide (à confirmer avec un plan d'exécution)
par contre, ce que l'on gagne d'un côté, on le perd de l'autre => lors d'une insertion, il faut mettre à jour les index, donc si tu as 30 indexes sur une table, lors de l'insertion il mettra à jour les 30 indexes
 
Mais ton pb manque de détails...

Reply

Marsh Posté le 16-06-2008 à 16:37:30    

@couak : quels détails manquent ? La description des tables ?

Reply

Marsh Posté le 16-06-2008 à 17:33:25    

@casimir : c'est quoi le plan d'exécution ?

Reply

Marsh Posté le 16-06-2008 à 18:11:35    

niveua détail, il faut commencer par dégrossir, et donner un max de détails, car le problème peut aussi bien provenir d'une mauvaise configuration de la base, de structure, de stats pas à jour, d'un hardware défaillant...
donc commence par regarder le plan d'exécution de ta requête SELECT (explications ici : http://www.orafaq.com/node/1420) et le temps d'exécution de la requête

Reply

Marsh Posté le 16-06-2008 à 20:36:56    

tu n'utiliserais pas toad des fois? (ben ouais je suis super soft dépendant :/ )

Reply

Marsh Posté le 16-06-2008 à 20:56:27    

Chacun son truc, ce n'est qu'une question de confort. Perso j'utilise sqldeveloper, comme toad, le plan d'exécution se fait en 1 clic

Reply

Marsh Posté le 17-06-2008 à 10:32:05    

@couak & casimir : ok j'ai vu d'où viennent mes soucis. J'ai supprimé des indexes, et c'est beaucoup + rapide. Je pense d'ailleurs que je vais regarder un tuto sur les indexes, pk'ils doivent être mal construits.
Merci de votre aide.
@++

Reply

Marsh Posté le 17-06-2008 à 19:27:13    

couak a écrit :

dans la plupart des cas, les indexes permettent une recherche rapide (à confirmer avec un plan d'exécution)
par contre, ce que l'on gagne d'un côté, on le perd de l'autre => lors d'une insertion, il faut mettre à jour les index, donc si tu as 30 indexes sur une table, lors de l'insertion il mettra à jour les 30 indexes
 
Mais ton pb manque de détails...


pour la perte de temps à l'insertion, ça dépend plus ou moins des SGBD.
 
de plus en plus, les SGBD marquent les index "dirty" durant les modifs, et créent un catalogue des lignes modifiées.
ceci permet d'améliorer les performances lors des insertion, tout en réduisant à peine les lectures (on lit d'abord l'index, puis on va lire les lignes du catalogue des lignes non indexées pour compléter)
 
ensuite, lorsque le sgbd a du temps, il va effectivement indexer ces lignes en background.
 
c'est notamment le cas des index "text" (pour faire des recherches comme dans google) : c'est pourquoi on ne voit pas les nouvelles lignes tout de suite quand on les ajoute, car la lecture des lignes non indexées est zappée car beaucoup trop lente et peut pertinante -puisque cela va modifier la pondération des scores des mots déjà indexés-)


Message édité par MagicBuzz le 17-06-2008 à 19:28:12
Reply

Marsh Posté le 17-06-2008 à 19:27:13   

Reply

Marsh Posté le 17-06-2008 à 19:30:29    

didine92 a écrit :

@couak & casimir : ok j'ai vu d'où viennent mes soucis. J'ai supprimé des indexes, et c'est beaucoup + rapide. Je pense d'ailleurs que je vais regarder un tuto sur les indexes, pk'ils doivent être mal construits.
Merci de votre aide.
@++


regarde dans ma signature, à un moment je parle des index (c'est loin d'être parfait, c'est très superficiel mais suffisant pour dégrossir)
 
quels étaient tes index ? en gros, il faut au moins un index unique (ou une clé primaire) sur chaque table, et l'utiliser le plus souvent possible. faire des clés étrangères entre les tables aussi aide bien pour les jointures. mais surtout, les index doivent être déclarés avec les champs dans le bon ordre (du plus utilisé/pertinant au moins utilisé/pertinant). et surtout, ne pas porter sur trop de champs.

Reply

Marsh Posté le 18-06-2008 à 09:36:14    

@magicBuzz : A titre d'exemple. J'ai une table horprev avec les champs type, code, numero, annee, jour, matricule, num_ordre, arrivee, depart qui sont tous en not null.
 
Sur cette table j'ai 3 indexes :
horprev_i (type,code,numero,jour,matricule,num_ordre)
horprev_i1(type,code,numero,jour,matricule,num_ordre,arrivee,depart)
horprev_i2(type,code,jour,matricule,num_ordre).
 
Je ne comprends pas bien l'intérêt de faire un indexe sur la table entière...
Je reprends cette BD que je n'ai pas créée, et j'ai des difficultés à comprendre le raisonnement.  
Je vais regarder ton tuto. Merci

Reply

Marsh Posté le 18-06-2008 à 13:31:17    

horprev_i est inutile car englobé dans horprev_i1
 
si type,code est unique (il y a de grandes chances) alors tous le reste des champs est inutile et sera plus source de ralentissement qu'autrechose
 
par contre si tu veux faire des recherches de toutes les lignes pour un jour donné et pour un matricule donné par exemple, il te faut un index (jour, matricule)
 
c'est comme ça que ça marche.
pour moi tes 3 index ci dessus sont grandement redondant, et certainement inutiles si (type,code) est unique, et même source de forts ralentissements, puisqu'Oracle s'amuse à indexer plusieurs fois de suite des champs inutilement, et lors de l'utilisation des index, évalue inutilement des informations dans les index alors qu'il serait aussi rapide de les lire dans la base (quand j'ai identifié une ligne, c'est aussi rapide de lire dans les données si le matricule est bon que dans l'index)

Reply

Marsh Posté le 18-06-2008 à 13:51:25    

ok, je commence à mieux comprendre. Alors type et code ne sont pas uniques, ils correspondent au type d'établissement fréquenté et à la section. Par contre le coup de la recherche pour un jour donné pour un matricule me fait comprendre des choses. Je crois qu'il y a un soucis d'analyse au départ sur la bd.
Merci

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed