UNION ALL ビューでパフォーマンスの問題があります。この問題は、ビューを 2 つの別々のビューに書き直すことで解決できますが、それではビューを作成する目的が無効になります。
簡単なテスト ケース (Oracle 11.2.0.3.0) を次に示します。実際のクエリでは、3 つではなく約 10 の異なるテーブルが使用されます。
CREATE TABLE t0 (id number, ref_id number);
CREATE INDEX i0 on t0(id);
CREATE TABLE t1 (id number, amount number);
CREATE INDEX i1 on t1(id);
CREATE TABLE t2 (id number, amount number);
CREATE INDEX i2 on t2(id);
insert into t0 select rownum, rownum * 10 from dual connect by rownum <= 100000;
insert into t1 select rownum, rownum * 10 from dual connect by rownum <= 100000;
insert into t2 select rownum, rownum * 10 from dual connect by rownum <= 100000;
CREATE OR REPLACE VIEW v2
AS
SELECT id, sum(amount) AS total_amount
FROM t1
GROUP BY id;
CREATE OR REPLACE VIEW v3
AS
SELECT id
,sum(amount) as total_amount
FROM (SELECT id, amount
FROM t1
UNION ALL
SELECT id, amount
FROM t2)
GROUP BY id
HAVING sum(amount) <> 0
;
CREATE OR REPLACE view v1
AS
SELECT *
FROM v2
UNION ALL
SELECT *
FROM v3;
次のクエリは 766 の get を使用します。push_pred(a) を追加しても何も起こりません。
select --+ first_rows
*
from t0, v1 a
where t0.ref_id = a.id
and t0.id = 1;
次のクエリは 16 取得で底をつきますが、最初のクエリと同じことを行い、t0 を 1 回ではなく 2 回スキャンするだけです。
select --+ first_rows
*
from t0, v2
where t0.ref_id = v2.id
and t0.id = 1
union all
select *
from t0, v3
where t0.ref_id = v3.id
and t0.id = 1;
私は何が欠けていますか?