我在程序中遇到了一些麻煩,當運行「大」集(800+父母,1300+孩子),它是非常慢(30 - 60秒)。如何優化流水線,弱類型遊標的使用
基本想法是獲取適合特定搜索條件的所有父記錄(及其各自的子女)以及需要計算的3條附加信息。
我對這個問題的方法是
- 創建與計算值附加字段自定義記錄型。
- 然後可以將對該記錄類型的引用傳遞給每個由主處理函數控制的函數。
- 由於計算每個父記錄的值,所以要將其記錄到記錄中。
每個過程GET_PARENT_RECORDS
和GET_CHILD_RECORDS
被稱爲每次搜索一次,並且每個計算功能運行N次(其中N是親本和/或子記錄的數量)。
問題1:這是正確的做法? (弱類型遊標,流水線函數)如果不是,那麼我應該如何處理這個問題,假設我可以重新做呢?
問題2:禁止完全重寫,是否有任何明顯的可以改進的代碼提供?
問題3:或者可能是別的什麼錯誤,因爲我注意到,當我運行幾次程序時,在20秒內返回相同的慢查詢?
包定義
create or replace
PACKAGE THIS_PKG AS
Type parentCursor IS REF CURSOR;
Type childCursor IS REF CURSOR;
Type ParentRecordType IS RECORD (
other_columns,
Extra_column_A,
Extra_column_B,
Extra_column_C,
Row_num);
--associative array
TYPE ParentArray IS TABLE OF ParentRecordType;
FUNCTION processParents(
p IN THIS_PKG. parentCursor
) RETURN ParentArray
PIPELINED
;
FUNCTION countSomething(some params…)
RETURN INT;
FUNCTION checkCondX (SomeParent IN ParentRecordType)
RETURN VARCHAR2;
FUNCTION checkCondY (SomeParent IN ParentRecordType)
RETURN VARCHAR2;
PROCEDURE GET_PARENT_RECORDS(other_parameters, Parents OUT THIS_PKG.parentCursor);
PROCEDURE GET_CHILD_RECORDS(other_parameters, Children OUT THIS_PKG.childCursor);
END THIS_PKG;
包體
-- omitted
FUNCTION processParents(
p IN THIS_PKG.parentCursor
) RETURN ParentArray
PIPELINED
IS
out_rec ParentArray;
someParent ParentRecordType;
BEGIN
LOOP
FETCH p BULK COLLECT INTO out_rec LIMIT 100;
FOR i IN 1 .. out_rec.COUNT
LOOP
out_rec(i).extra_column_A := countSomething (out_rec(i).field1, out_rec(i).field2);
out_rec(i).extra_column_B := checkCondX(out_rec(i));
out_rec(i).extra_column_C := checkCondY(out_rec(i));
pipe row(out_rec(i));
END LOOP;
EXIT WHEN p%NOTFOUND;
END LOOP;
RETURN;
END processParents;
PROCEDURE GET_PARENT_RECORDS(
some_columns,
Parents OUT THIS_PKG. parentCursor) IS
BEGIN
OPEN Parents FOR
SELECT *
FROM TABLE(processParents (CURSOR(
SELECT *
FROM (
--some select statement with quite a few where clause
--to simulate dynamic search (from pre-canned search options)
)
))) abc
WHERE abc.extra_column_C like '%xyz%' --(xyz is a user given value)
;
END GET_PARENT_RECORDS;
更新 一些探索昨天DID和整個任務批處理SQL優化器(蟾蜍)來了。我插入包裝,這是我得到的。
批優化結果
複雜的查詢
有問題的查詢
你有沒有做過任何分析以指出問題出在哪裏? – 2013-04-03 23:29:18
@BobJarvis我懷疑我可以做一個全面的分析上,因爲我不是DBA和可能難以挖掘他的時間。但是我對查詢進行了一些分析並附上了兩個解釋計劃。這是你在說什麼嗎? – user1766760 2013-04-04 18:02:36
從不「禁止一個完全重寫的」,當涉及到SQL(或PL/SQL)。流水線是一個非常棒的功能,但通常可以通過改進的聲明式方法來消除。 – 2013-11-08 21:24:58