2013-05-28 6 views
0

J'ai 3 tables trader, city_state, city_present.Performances des requêtes SQL Oracle

J'ai 4millions de lignes dans la table trader et ma requête prend au moins 20sec. Peu d'enregistrements dans city_present et dans la table des villes.

Voici ma requête.

 
    

select t.trader_id, t.name, t.city, t.state from ( SELECT distinct c.city, c.state FROM city_present p,city_state c WHERE p.name = 'TEST_TEST' AND c.city = p.city AND c.state = p.state ) cs, trader t where AND t.city = cs.city AND t.state = cs.state AND t.name = 'john test' AND t.is_valid= 1

J'ai index sur la clientèle (ville, état, nom, valid_customer) prend sous-requête moins d'une seconde .. il est question externe qui prend environ 20sec. Est-ce que quelqu'un peut m'aider s'il vous plaît comment réduire le temps de requête.

+1

Pour les débutants, montrer le plan d'explication aiderait. – OldProgrammer

+0

Combien de lignes sont renvoyées par votre requête? –

Répondre

0

Je suppose que vous avez un index sur trader.name, incluant éventuellement trader.is_valid?

Et le distinct est-il vraiment nécessaire? Est-ce que cela doit vraiment être une vue en ligne, ou pourrait-il être une jointure régulière?

+0

environ 35 lignes sont retournées. – user12121

+0

Ai-je besoin d'un index sur le nom du trader, les variables is_valid, city, state ou simplement les colonnes name et is_valid? – user12121

+0

Vous avez presque certainement besoin d'un index sur trader.name au minimum. Le fait que vous en ayez besoin sur is_valid dépend du temps qu'il vous faudra pour trouver l'is_valid = 1 de l'index sans aller à la table. Combien de lignes avez-vous pour chaque valeur de is_valid? Vous n'avez probablement pas besoin de toutes les colonnes du trader dans l'index - essayez-le sans d'abord. –

0

Il y a certaines choses que vous pouvez essayer sans rien ajouter à votre schéma: dans votre sous-requête vous sélectionnez jamais rien de city_present, de sorte que vous pouvez le transformer en IN/EXISTS

select t.trader_id, t.name, t.city, t.state from 
(
SELECT c.city, c.state 
FROM city_state c 
WHERE EXISTS (
    select null 
    from city_present p 
    where 
    p.name = 'TEST_TEST' 
    AND c.city = p.city 
    AND c.state = p.state) 
) 
cs, trader t 
where 
AND t.city = cs.city 
AND t.state = cs.state 
AND t.name = 'john test' 
AND t.is_valid= 1 

Ensuite, la même chose à cs. Ainsi, vous pouvez réécrire:

select t.trader_id, t.name, t.city, t.state from 
trader t 
where 
exists (
    SELECT null 
    FROM city_state c 
    WHERE EXISTS (
     select null 
     from city_present p 
     where 
     p.name = 'TEST_TEST' 
     AND c.city = p.city 
     AND c.state = p.state) 
    AND t.city = c.city 
    AND t.state = c.state 
) 
AND t.name = 'john test' 
AND t.is_valid= 1 

Vous pouvez également essayer aplatir les sous-requêtes:

select t.trader_id, t.name, t.city, t.state from 
trader t 
where 
exists (
    SELECT null 
    FROM city_present p,city_state c 
    WHERE p.name = 'TEST_TEST' 
    AND c.city = p.city 
    AND c.state = p.state 
    AND t.city = c.city 
    AND t.state = c.state 
) 
AND t.name = 'john test' 
AND t.is_valid= 1 

De là, vous devriez étudier sur l'indexation:

  • trader.name et/ou commerçant .id
  • (city_state.city, city_state.state) et (city_present.city, city_present.state)
+0

Merci, amélioration des performances après l'ajout d'index. – user12121

Questions connexes