|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Membre éprouvé
![]() Inscription : septembre 2004 Messages : 465 ![]() |
(re)Bonjour.
J'ai un souci de performances sur cette requête assez simple: Code :
t1 fait 64 000 lignes, et t2 fait 134 000 lignes. L'insertion de ce select dans une table vide prend 2h...... alors que t1 contiendra 900 000 lignes. L'explain plan est en pièce joint. C'est le MERGE qui coince... Une précision: dans la table t2, chaque intervalle [borneinf; bornesup] n'est qu'en un seul exemplaire, et les intervalles ne se chevauchent pas. Il faudrait que pour chaque ligne, la comparaison s'arrête dès qu'on en a trouvé un (il peut n'y avoir aucun intervalle). Merci pour votre aide! |
||
|
|
00
|
|
|
#2 |
|
Membre régulier
![]() Inscription : septembre 2008 Messages : 84 ![]() |
Bonjour,
Est ce que l'exécution du select seul (sans insert) prend autant de temps ? (je suppose que non) Si non, quel est la structure de la table à remplir ? comporte t elle des indexes, des clés étrangères ? Si oui, essayez de désactiver les index (et si besoin les clé étrangères) le temps de l'insertion, ca devrait limiter le travail de la base durant l'insert. |
|
|
00
|
|
|
#3 |
|
Membre expérimenté
![]() François Inscription : février 2010 Messages : 305 ![]() |
Si c'est pour mettre dans une table vide, c'est plus rapide de faire un create table qu'un gros insert.
|
|
|
00
|
|
|
#4 |
|
Membre éprouvé
![]() Inscription : septembre 2004 Messages : 465 ![]() |
Le SELECT ne prend pas autant de temps (SqlDeveloper me ramène les 50 premières lignes en 11s) mais c'est déjà trop.
La table cible n'a ni index, ni clé primaire (je l'ai virée avant l'insertion), juste quelques contraintes not null. Les stats sont calculées sur les 3 tables. Il y a un vrai problème sur le SELECT, car le MERGE me fait visiter 21 millions de lignes... |
|
|
00
|
|
|
#5 |
|
Membre éprouvé
![]() Inscription : septembre 2004 Messages : 465 ![]() |
|
|
|
00
|
|
|
#6 |
|
Membre éprouvé
![]() Inscription : septembre 2004 Messages : 465 ![]() |
Mon DBA sèche aussi.
Personne n'a une idée?Il doit forcément y avoir un truc pour éviter qu'une simple comparaison ne provoque pas un produit cartésien...
|
|
|
00
|
|
|
#7 | ||||
|
Membre éprouvé
![]() Inscription : septembre 2004 Messages : 465 ![]() |
RESOLU!
Le DBA (c'est mon pote!!!! ) a trouvé la soluce en cherchant sur ORAFAQ: Tuning "BETWEEN" Queries.Au chapitre "Range Table Single-row Lookup" de la page. Le truc: on remplace Code :
Code :
Je suis passé de 2 heures à ...... 2 secondes!!! ![]() ![]() ![]() A garder précieusement pour l'utilisation des BETWEEN!
|
||||
|
|
00
|
|
|
#8 |
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
Comment est (sont) créé l'index sur table2 ?
Un index composite sur (borneinf,bornesup) ou 2 index séparés ? Si l'index est composite, est il unique ? ça pourrait donner des infos à l'optimiseur. Les stats sont elles à jour et y a t il des histogrammes sur les colonnes borneinf et bornesup ? Analyser l'index est aussi une bonne chose. Quelle est la version d'oracle ? |
|
|
00
|
|
|
#9 |
|
Membre régulier
![]() Inscription : septembre 2008 Messages : 84 ![]() |
En fait, ce n est pas vraiment un produit cartesien : 64*134 ~ 8500 >> 21, mais c'est quand meme une combinatoire de possibilités
Une solution de contournement serait de traiter les lignes de table1 par paquets de n lignes triées. Ca permettrait de limiter les combinaisons |
|
|
00
|
|
|
#10 |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
Ajoutez plutôt un petit jeu d’essai avec les "create table" et index etc. plus la requête et n’oubliez pas de préciser la version d’Oracle.
|
|
|
00
|
|
|
#11 | |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
Citation:
|
|
|
|
00
|
Copyright © 2000-2012 - www.developpez.com