Oracle 从C++程序运行的查询比SQL加起来占用的查询时间长了48万亿倍。

Oracle 从C++程序运行的查询比SQL加起来占用的查询时间长了48万亿倍。,oracle,Oracle,我们遇到了一个难以解释的问题。在SQLPlus或TAD中,它运行在1/2秒,但是当通过分布式事务从C++程序运行时,它花费41分钟。直到本周,这段代码从C++代码中运行了10000秒, 数据库、代码或运行代码的W2k服务器中没有任何更改 当从代码运行时,它有非常高的db文件顺序读取超过1000000 当从SQL运行完全相同的语句时,加上db文件顺序读取为8 所以,当通过代码和DT运行时,同一语句比从sqlplus运行时要多做100000倍的工作 我们执行以下查询以查找正在读取的块 选择p1文件、

我们遇到了一个难以解释的问题。在SQLPlus或TAD中,它运行在1/2秒,但是当通过分布式事务从C++程序运行时,它花费41分钟。直到本周,这段代码从C++代码中运行了10000秒,

数据库、代码或运行代码的W2k服务器中没有任何更改

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

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

所以,当通过代码和DT运行时,同一语句比从sqlplus运行时要多做100000倍的工作

我们执行以下查询以查找正在读取的块 选择p1文件、p2块、p3类 从v$session\u等待 其中event='db file sequential read'

它们是查询中使用的表。它一遍又一遍地阅读表格,但解释计划表明只应阅读8个块

两张桌子的大小都在10吉格左右

这是陈述和解释计划

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分钟才能解决的事情?有没有办法确定这一点?

要找到实际使用的计划,可以使用sql\u id查询v$sql\u计划。最简单的方法是在查询中添加注释以使其唯一,例如

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

然后运行查询。通过从v$sql查询,您可以找到查询的sql\u ID,例如:

select sql_id, sql_fulltext
from v$sql
where upper(sql_fulltext) like '%FROM C++%';
然后使用该SQL\u ID,您可以查询v$SQL\u plan以获取该计划,或者更好地使用以下查询:

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