我在下面的场景中运行,这给我带来了很多麻烦,因为我无法找到我所看到的行为的确切解释。我声明了以下内容:
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;
第二种表现的差异很大。
有谁知道什么可以解释这种行为?
答案 0 :(得分:1)
您是否考虑了缓存的影响?我不认为。
如果您运行第一个查询定时,则运行第二个查询定时,其中testvar1_param值相同,第二个查询在明显不同的时间内完成。首先运行哪个查询无关紧要,第二个版本会更好。
这是因为两个查询中的where谓词相同,并且结果集中的数据在两个查询中都相同。通常后续查询当你反对索引查询时,相同的查询运行得更快,因为你从不去表获取结果集,它来自缓存它的SGA。
尝试对testvar1_param使用不同的值,并使用完全不同的parm值运行10个查询。他们会非常接近。
你正在使用tkprof吗?
答案 1 :(得分:1)
对于一见钟情无法解释的性能问题:打开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计划的样子。
对于你的问题 - 必须以随机方式一个接一个地获取大量行 - 我希望找到
这些场景非常重要,不要解析每个选择。解析可能比执行花费更多时间。
剩下的一个问题是:为什么要逐一获取所有行?这是某种数据复制操作吗?
答案 2 :(得分:0)
我的意思是指(因为它是开发,对吗?)
ALTER SYSTEM SET TIMED_STATISTICS = TRUE;
这改善了oracle在跟踪性能时为您提供的内容。