从C++程序运行时查询比从SQL Plus运行时长4800倍

use*_*226 7 oracle

对于无法解释的查询,我们遇到了严重的问题.在SQL-plus或TOAD中它以1/2秒运行,但是当通过分布式事务从C++程序运行时,它需要41分钟.直到本周,这已经在一秒钟内从C++代码中运行了10,000次.

数据库或代码或运行代码的W2k服务器没有任何变化.

从代码运行时,它具有非常高的db文件顺序读取超过1,000,000

当从SQL运行完全相同的语句加上db文件时,顺序读取为8

所以同样的声明在通过代码和DT运行时比从sqlplus运行多做100,000倍.

我们做了以下查询来查找正在读取的块SELECT p1"file#",p2"block#",p3"class#"FROM v $ session_wait WHERE event ='db file sequential read'

它们是查询中使用的表.它正在反复阅读表格,解释计划表明只应读取8个块

两张桌子的面积都是~10 gig

这是法规和解释计划

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  
Run Code Online (Sandbox Code Playgroud)

我们怎样才能看到实际运行时语句的实际计划是什么?我们可以告诉它正在阅读上面的表格.是否有可能实际计划与我们所看到的不同,实际上正在进行某种类型的笛卡尔联合或者需要40分钟才能解决的奇怪事情?有没有办法确定?

Ste*_*ell 5

要查找使用的实际计划,可以使用sql_id查询v $ sql_plan.最简单的方法是在查询中添加注释以使其唯一,例如

select /* FROM C++ */ ....
Run Code Online (Sandbox Code Playgroud)

select /* FROM SQLPLUS */ ....
Run Code Online (Sandbox Code Playgroud)

然后运行查询.通过查询v $ sql,您可以找到查询的SQL_ID,例如:

select sql_id, sql_fulltext
from v$sql
where upper(sql_fulltext) like '%FROM C++%';
Run Code Online (Sandbox Code Playgroud)

然后使用该SQL_ID,您可以查询v $ sql_plan以获取计划,或者更好,使用以下查询:

select * from table(dbms_xplan.diplay_cursor('SQL ID OBTAINED ABOVE'));
Run Code Online (Sandbox Code Playgroud)