2009-09-15 3 views
0

La requête suivante (V_TITRATION_RESULTS) est une vue utilise un pivot ligne à la colonne qui retourne environ 20 000 lignes:Tuning lignes à Col. requêtes

SELECT test.created_on as "Created On", 
     r_titr as "Titrator", 
     r_fact as "Factor" 
    FROM (SELECT test_id, 
       MAX(CASE WHEN result_tmpl_id = 2484 THEN result END) r_titr, 
       MAX(CASE WHEN result_tmpl_id = 2483 THEN result END) r_fact 
      FROM (SELECT lims.test.* 
        FROM lims.test 
       WHERE test_tmpl_id = 867) 
      JOIN lims.result USING (test_id) 
     GROUP BY test_id) 
    JOIN lims.test test USING (test_id) 

Je voudrais lancer une recherche sur la vue de retourner seulement les essais depuis le début de Septembre:

SELECT * FROM V_TITRATION_RESULTS WHERE "Created On" > DATE '2009-09-01' 

le « GET regimes » tant pour la vue et requête filtrée sont identiques, et les statistiques de traces (ci-dessous) pour les deux requêtes sont similaires indiquant les lignes ne sont pas filtrées avant ils ont tous été traités.

    VIEW  Filtered  Diff 
Physical Reads 81730  83946  2216 
Logical Reads 364488  344063 -20425 
Sort Rows  632194  632193  -1 
ROWID Gets  580778  580778   0 
Chained Gets  101823  101823   0 
Memory (kB)   307   324  17 
Scan Rows    3   3   0 
Scan Gets    3   3   0 
Sorts In Mem   4   4   0 
Temp Segments   1   1   0 
Scan Short   3   3   0 
CPU Total (sec) 8.13   7.3  -0.83 
First Row  2m 12s  2m 40s  
Last Row   18s   0s  

Comment puis-je réécrire mon avis afin qu'une condition WHERE filtrera les tests avant le pivot ligne à la colonne?

+0

Quelle version d'Oracle? –

Répondre

3

Steven, je me demande pourquoi vous ne pouvez pas utiliser:

CREATE OR REPLACE VIEW V_TITRATION_RESULTS AS 
    SELECT lt.test_id, 
     lt.created_on, 
     MAX(CASE WHEN result_tmpl_id = 2484 THEN result END) 'titrator', 
     MAX(CASE WHEN result_tmpl_id = 2483 THEN result END) 'factor' 
    FROM lims.test lt 
    JOIN lims.result USING (test_id) 
    WHERE lt.test_tmpl_id = 867 
GROUP BY lt.test_id, lt.created_on 

Se débarrasser des sous-sélections améliorera les performances des requêtes. En supposant que Oracle 9i + - esprit que vous pouvez utiliser Subquery Factoring (WITH clause) dans les vues.

Ensuite, vous pouvez utiliser:

SELECT vtr.* 
    FROM V_TITRATION_RESULTS vtr 
WHERE vtr.created_on > TO_DATE('2009-09-01', 'YYYY-MM-DD') 
+0

Bonnes choses .... solide –

+0

@David: Merci. –

+0

Si j'ai besoin de plusieurs autres champs de test (disons 10), le regroupement par toutes les colonnes nécessaires reste-t-il le plus efficace (pour permettre le filtrage) même s'il suffit de le grouper par PK (test_id)? – Steven

1

Ceci est un peu hors de mon territoire, mais s'il vous plaît regarder dans l'utilisation de variables de liaison au lieu de littéraux dans votre instruction SELECT comme un moyen d'améliorer les performances.

Voir http://www.akadia.com/services/ora_bind_variables.html et http://www.dba-oracle.com/concepts/views.htm. Plus précisément, les sections de prédiction poussant pourraient vous intéresser.

+0

@David: Vous ne pouvez pas utiliser de variables de liaison dans une vue –

+0

@rexem: Pas dans la vue elle-même, mais dans l'instruction SELECT qui fait référence à la vue. –

+0

@David: C'est juste, mais c'est la vue qui a besoin d'être optimisée avant toute chose. –

Questions connexes