[SQL] requete trop lente

requete trop lente [SQL] - SQL/NoSQL - Programmation

Marsh Posté le 13-03-2007 à 17:15:50    

Bonjour,
Je suis devant un problème que je n'arrive pas à résoudre efficacement.
J'ai une requete SQL qui ressemble à ça
 

Code :
  1. select e.ID,e.NOM,e.PRENOM,e.STATUS from EMPLOYEE e where e.STATUS='EXISTANT'
  2. AND NOT EXISTS(SELECT p.PID FROM PROFILE where p.PID=e.ID);


 
Mon problème est que cette requete(Jointure) met trop de temps à s'exécuter sur deux tables qui font
à peu pres les tailles suivantes
EMPLOYEE:70000 entrees
PROFILE:2 000 000 entrées
 
Comment pourrais faire pour la rendre plus rapide en terme de temps d'exécution
 

  • Procédures/fonctions stockées mais je ne vois pas comment faire pour la jointure NOT EXISTS  
  • Vues statique ou dynamique mais est ce que ça résoud le problème vraiment.


Merci pour votre coup de main


---------------
"Rendez tout aussi simple que possible mais ne simplifierez rien" Albert Einstein
Reply

Marsh Posté le 13-03-2007 à 17:15:50   

Reply

Marsh Posté le 13-03-2007 à 20:14:27    

Le comportement dépend du sgbd utilisé, de la manière dont c'est administré, etc.
Comme tu ne spécifies pas ton sgbd, j'en conclus (une nouvelle fois) que tu utilises mysql
Moi perso j'aurais fait une belle jointure et pas une requête imbriquée :  

Code :
  1. SELECT
  2.   e.ID, e.NOM, e.PRENOM, e.STATUS
  3. FROM
  4.   EMPLOYEE e LEFT JOIN PROFILE p ON p.pid = e.ID
  5. WHERE
  6.   e.STATUS = 'EXISTANT'
  7.   and p.pid IS NULL


 
Je te conseille fortement de créer les indexes adéquat afin d'accélérer les recherches

Code :
  1. ALTER TABLE employee ADD INDEX ix_employee (id, status);
  2. ALTER TABLE profile ADD INDEX ix_profile (pid);


Si le champ ID de la table employee et/ou le champ PID de la table profile sont des clés primaire, il est inutile de les indexer. Dans ce cas là ajoute juste un index sur le champs "'status" de la table employee

Reply

Marsh Posté le 28-03-2007 à 17:17:25    

Merci Couak,
J'ai adopté une autre manière de faire.
1-Récupérer la liste des employés qui sont marqués EXISTANT.
2-Ensuite je parcours la liste des profiles pour voir si un employé a un profile non NULL.
ça marche.
Sinon j'utilise Oracle comme SGBD.

Reply

Marsh Posté le 28-03-2007 à 17:21:50    

sans tout réécrire, tu peux remplacer le "not exists" par un "not in", puisqu'apparement dans les dernières versions d'Oracle le IN est plus rapide que le EXISTS.
 
ceci dit, c'est plus un problème d'indexes que de requête, elle est tout à fait bonne. (et fait en interne la même chose que la jointure externe de couak normalement).
 
pour créer un index avec Oracle, la syntaxe c'est :
 
create index emp_id_status on employee (id, status);

Reply

Marsh Posté le 28-03-2007 à 17:22:17    

si l'index est unique (ce qui devrait être le cas ici) alors c'est "create unique index"

Reply

Marsh Posté le 28-03-2007 à 17:53:46    

  Solution en ORACLE 8
      SELECT  e.ID, e.NOM, e.PRENOM, e.STATUS
      FROM
       EMPLOYEE e, PROFILE p WHERE p.pid = e.ID(+) and
       (e.STATUS = 'EXISTANT' and p.pid IS NULL);
 
et ça marche
 
A+

Reply

Sujets relatifs:

Leave a Replay

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