Pro*Cパフォーマンスの違い
-
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;
2番目のパフォーマンスは大きなマージンによって異なります。
誰もがこの行動を説明できるものを知っていますか?
解決
一目で説明できないように見えるパフォーマンスの問題については、待機を含むSQLトレースをオンにします。
ALTER SESSION SET TRACEFILE_IDENTIFIER = "some_unique_identifier";
dbms_support.start_trace (binds=>true,waits=>true);
コードを実行し、コミットし、優雅に切断します。 dbms_support.stop_traceを使用しないでください。これは、rowsource操作のスプールを防ぐ可能性があるためです。生成されたTraceFileには、SQLおよびRowsource操作に影響を与える待機イベントが解析された正確なSQLテキストが見つかります。 Rowsource操作は、SQLの実行中にSQLプランがどのように見えたかを示しています。
- 区画の数を確認してください
- 使用されているバインド変数を確認してください。
- 予想される計画については、rowsource操作を確認してください。
あなたの問題のために - ランダムな方法でたくさんの行を1つずつ取得する必要があります - 私は見つけることを期待しています
- 1カーソル宣言
- 1つのパース
- カーソルを開設/取得/閉じるループ
これらのシナリオがすべての選択を解析しないことは非常に重要です。解析は、実行よりも時間がかかる場合があります。
残っている質問の1つは、なぜすべての行を1つずつ取得するのですか?これはある種のデータコピー操作ですか?
他のヒント
キャッシュの効果を説明していますか?私はそうではないと思います。
最初のクエリのタイミングを実行すると、TestVar1_Param値が同じである2番目のクエリのタイミングを実行すると、2番目は著しく異なる時間で完了します。どのクエリが最初に実行されるかは関係ありません。2番目のバージョンの方が良くなります。
これは、ここで述語が両方のクエリで同じであり、結果セットのデータが両方のクエリで同じであるためです。通常、後続のクエリは、結果を取得するためにテーブルに行かないため、インデックス付きクエリに反対すると、同一のクエリがはるかに速く実行されます。
TestVar1_Paramに異なる値を使用してみて、まったく異なるPARM値でそれぞれの10のクエリを実行してください。彼らは非常に時間的に非常に近いでしょう。
あなたはtkprofを使用していますよね?
タイミングとは、つまり(開発なので、そうですか?)
ALTER SYSTEM SET TIMED_STATISTICS = TRUE;
これにより、Oracleがパフォーマンスのトレースで提供するものが改善されます。