2011-11-29 42 views
7

我們遇到了一個嚴重的問題,因爲查詢無法解釋說明。在SQL-plus或TOAD中,它在1/2秒內運行,但是當通過分佈式事務從C++程序運行時,需要41分鐘。直到本週之前,這一切都在C++代碼中運行了10,000次,都在一秒之內。從C++程序運行時,查詢所需時間比SQL Plus所用時間長4800倍

數據庫或運行代碼的代碼或W2k服務器沒有任何變化。

從時完全一樣的語句從SQL加上數據庫文件順序讀取運行它具有非常高的數據庫文件順序讀取超過1,000,000

代碼運行的時候是8

所以相同的語句是幹什麼100000通過代碼和DT運行時比從sqlplus運行更多的工作。

我們做了以下查詢找到正在讀什麼塊 SELECT P1「文件#」,P2「塊#」,P3「類#」 從V $ SESSION_WAIT WHERE事件=「數據庫文件連續讀」

它們是查詢中使用的表格。它是一遍又一遍地讀表還解釋計劃表明只有8塊應該讀

兩個表的大小

這裏〜10演出是statment和解釋計劃

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 

我們如何看到實際計劃實際運行時的實際計劃?我們可以告訴它正在讀上面的表格。是否有可能實際的計劃與我們所看到的實際計劃不同,實際上是在進行某種笛卡爾連接或者需要40分鐘才能解決的問題?有沒有一種方法來確定?

回答

5

要查找使用的實際計劃,可以使用sql_id查詢v $ sql_plan。最容易做的事情,就是把評論的查詢,使其獨特的,如

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

select /* FROM SQLPLUS */ .... 

然後運行該查詢。通過從V $ SQL查詢,你可以找到查詢的SQL_ID,如:

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

然後使用SQL_ID,可以查詢V $ SQL_PLAN拿到計劃,或更好,使用以下查詢:

select * from table(dbms_xplan.diplay_cursor('SQL ID OBTAINED ABOVE'));