2011-11-29 13 views
7

Mamy poważny problem z kwerendy, która wymyka się wyjaśnieniu. W SQL-plus lub TOAD działa przez pół sekundy, ale po uruchomieniu z programu C++ za pośrednictwem transakcji rozproszonej zajmuje 41 minut. Do tego tygodnia liczba ta wynosiła 10 000 razy z kodu C++ poniżej sekundy.Kwerenda trwa 4800x dłużej, gdy uruchamiany z programu C++ niż z SQL Plus

Nic nie zmieniło się w DB lub kodzie lub serwerach W2k z kodem.

podczas pracy z kodem to bardzo wysoki db pliku sekwencyjnego odczytu ponad 1,000,000

kiedy dokładnie to samo stwierdzenie jest uruchamiany z SQL * Plus pliku db sekwencyjnego odczytu wynosi 8

Tak samo stwierdzenie robi 100,000x więcej pracy po uruchomieniu przez kod i DT niż z sqlplus.

zrobiliśmy następującą kwerendę, aby znaleźć to bloki są odczytywane SELECT P1 "Plik nr" P2 "blok #" P3 "class #" zv $ session_wait GDZIE event = 'sekwencyjny plik db odczytu'

i są to tabele użyte w zapytaniu. Jest czytania tabel w kółko jeszcze wyjaśnić Plan wskazuje jedynie 8 bloków należy czytać

obie tabele są ~ 10 gig w rozmiarze

oto statment i wyjaśnić Plan

SELECT COUNT (*) 
    FROM student st, testinstance ti 
WHERE st.dataset_id = :b2 
    AND st.student_id = ti.student_id 
    AND ti.testinstance_id > :b1 
    AND NOT EXISTS (
      SELECT 1 
      FROM programscoringexclusion ex 
      WHERE ex.program_id = wfgeneral.getprogramid (:b3) 
      AND ex.testfamily_id = ti.testfamily_id 
      AND NVL (ex.test_level, NVL (ti.test_level, '*')) = 
                 NVL (ti.test_level, '*') 
      AND NVL (ex.battery, NVL (ti.battery, '*')) = 
                 NVL (ti.battery, '*') 
      AND NVL (ex.form, NVL (ti.form, '*')) = NVL (ti.form, '*')) 

      Plan 
SELECT STATEMENT CHOOSECost: 2      
    9 SORT AGGREGATE Bytes: 43 Cardinality: 1     
     8 FILTER    
      5 NESTED LOOPS Cost: 2 Bytes: 43 Cardinality: 1   
       2 TABLE ACCESS BY INDEX ROWID TABLE BBOX.TESTINSTANCE Cost: 1 Bytes: 32 Cardinality: 1  
        1 INDEX RANGE SCAN INDEX (UNIQUE) BBOX.XXPK0TESTINSTANCE Cost: 1 Cardinality: 1 
       4 TABLE ACCESS BY INDEX ROWID TABLE BBOX.STUDENT Cost: 1 Bytes: 11 Cardinality: 1  
        3 INDEX UNIQUE SCAN INDEX (UNIQUE) BBOX.XXPK0STUDENT Cost: 1 Cardinality: 1 
      7 TABLE ACCESS BY INDEX ROWID TABLE BBOX.PROGRAMSCORINGEXCLUSION Cost: 1 Bytes: 37 Cardinality: 1   
       6 INDEX RANGE SCAN INDEX BBOX.XXIE1PROGRAMSCORINGEXCLUSION Cost: 1 Cardinality: 1 

jak możemy zobaczyć, jaki jest faktyczny plan dla stwierdzenia, kiedy faktycznie działa? Możemy powiedzieć, że czyta powyższe tabele. Czy to możliwe, że rzeczywisty plan jest inny niż ten, który widzimy, i faktycznie robi coś w rodzaju kartezjańskiego połączenia lub czegoś dziwnego, co zajmuje 40 minut, aby rozwiązać? czy istnieje sposób na określenie tego?

Odpowiedz

5

Aby znaleźć rzeczywisty plan, można użyć v sql_plan z parametrem sql_id. Najłatwiej zrobić, to umieścić komentarz w zapytaniu, aby to wyjątkowe, np

select /* FROM C++ */ .... 

i

select /* FROM SQLPLUS */ .... 

Następnie uruchom kwerendę. Przez odpytywanie od v $ sql można znaleźć SQL_ID zapytania, np:

select sql_id, sql_fulltext 
from v$sql 
where upper(sql_fulltext) like '%FROM C++%'; 

Następnie przy użyciu tego SQL_ID, można wyszukać V $ sql_plan dostać plan, albo lepiej, należy użyć następującego zapytania:

select * from table(dbms_xplan.diplay_cursor('SQL ID OBTAINED ABOVE')); 
Powiązane problemy