我在程序上遇到了一些问题;当运行“大”组(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;
更新 昨天做了一些探索,发现了 Quest Batch SQL Optimizer(来自 Toad)。我插入了包裹,这就是我得到的。
批处理优化器结果
复杂查询
有问题的查询