我在以下情况下跑步,这给我带来了很多头痛,因为我找不到对自己所看到的行为的确切解释。我宣布以下内容:

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,因为它可能会阻止行驶行动的行驶。在生成的TraceFile中,您会在解析时找到确切的SQL文本,对SQL和Rowsource操作产生影响的等待事件。 Rowsource操作显示了运行SQL时SQL计划的确切外观。

  • 检查解析的数量
  • 检查是否使用的绑定变量。
  • 检查Rowsource操作是否预期计划。

出于您的问题 - 必须随机获取很多行 - 我希望找到

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

对于这些情况,不要分析每个选择非常重要。解析可能比执行时间更多。

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

其他提示

您是否正在考虑缓存的效果?我认为不是。

如果运行第一个查询时间,则运行第二个查询时间,其中testvar1_param值相同,第二个查询时间是明显不同的时间。首先运行哪个查询并不重要,第二个版本的效果会更好。

这是因为两个查询中的谓词都相同,并且结果集中的数据在两个查询中都是相同的。通常,当您反对索引查询时,随后的查询相同的查询速度要快得多,因为您永远不会转到表格以获取结果集,它来自SGA被缓存的SGA。

尝试使用不同的值用于testVar1_param,并以完全不同的PARM值从每个查询中运行10个查询。他们将非常接近时间。

您正在使用tkprof吗?

通过时间安排,我的意思是(既然是发展,对吗?)

ALTER SYSTEM SET TIMED_STATISTICS = TRUE;

这改善了Oracle为您提供表演的东西。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top