Pro*C性能差异



我在下面的场景中运行,这让我很头疼,因为我找不到对所看到的行为的确切解释。我有以下声明:

struct test_struct
{
    long testv1;
    char testv2[51];
    long testv3;
};

以及Oracle 10g:中的相应表

CREATE TABLE test_table
(
    testv1 NUMBER(10, 0),
    testv2 VARCHAR(50),
    testv3 NUMBER(4, 0)
);

要访问此表中的数据,我有一个功能:

bool getTestData(long test_var1, struct test_struct *outStruct)

在这里,我看到了我需要解释但无法解释的差异。如果函数的主体看起来像这样:

EXEC SQL BEGIN DECLARE SECTION;
    long testvar1_param = test_var1;
    struct test_struct *resStruct = outStruct;
EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT testv1, testv2, testv3
    INTO :resStruct
    FROM test_table
    WHERE testv1 = :testvar1_param;

如果函数体看起来像:,我会得到较慢的性能

EXEC SQL BEGIN DECLARE SECTION;
    long testvar1_param = test_var1;
    long *testv1_res = &(outStruct->testv1);
    char *testv2_res = outStruct->testv2;
    long *testv3_res = &(outStruct->testv3);
EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT testv1, testv2, testv3
    INTO :testv1_res, :testv2_res, :testv3_res
    FROM test_table
    WHERE testv1 = :testvar1_param;

第二场比赛的表现大不相同。

有人知道是什么可以解释这种行为吗?

对于乍一看无法解释的性能问题:启用包括等待在内的sql跟踪。

ALTER SESSION SET TRACEFILE_IDENTIFIER = "some_unique_identifier";
dbms_support.start_trace (binds=>true,waits=>true);

运行您的代码,使其提交并优雅地断开连接。不要使用dbms_support.stop_trace,因为它可能会阻止行源操作的后台处理。在生成的跟踪文件中,您将在解析时找到确切的sql文本,等待影响sql和行源操作的事件。rowsource操作显示了运行sql时sql计划的确切外观。

  • 检查解析数
  • 检查是否使用绑定变量
  • 请检查行源操作以获得预期的计划

对于你的问题——必须以随机的方式一个接一个地提取很多行——我希望找到

  • 1个游标声明
  • 1个解析
  • 打开/获取/关闭光标的循环

对于这些场景来说,不解析每个选择是非常重要的。解析可能比执行花费更多的时间。

剩下的一个问题是:为什么要一行接一行地获取所有行?这是某种数据复制操作吗?

您是否考虑了缓存的影响?我想不会。

如果运行第一个定时查询,然后运行第二个定时查询(其中testvar1_param值相同),则第二个在明显不同的时间内完成。先运行哪个查询并不重要,第二个版本会更好。

这是因为where谓词在两个查询中都是相同的,结果集中的数据在两个搜索中都是一样的。通常,当您使用索引查询时,后续查询相同的查询运行得更快,因为您从不去表中获取结果集,它来自缓存结果集的SGA。

尝试对testvar1_param使用不同的值,并使用完全不同的parm值从中运行10个查询。他们很快就会非常接近。

你在用tkprof吧?

我所说的时间是指(既然是开发,对吧?)

ALTER SYSTEM SET TIMED_STATISTICS = TRUE;

这提高了oracle在性能跟踪方面的性能。

相关内容

  • 没有找到相关文章

最新更新