-
26-10-2019 - |
题
我在以下情况下跑步,这给我带来了很多头痛,因为我找不到对自己所看到的行为的确切解释。我宣布以下内容:
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为您提供表演的东西。