SQL优化 第八章 案例模拟 8.3 FILTER优化1

8.3.1 数据环境准备

drop table test1;

drop table test2;

drop table test3;

create table test1 as select * from dba_objects;

create table test2 as select * from test1;

create table test3 as select * from test1;

insert into test2  select * from test2;

insert into test2  select * from test2;

insert into test3  select * from test3;

insert into test3  select * from test3;

create index ix_test1_01 on test1(object_id);

create index ix_test2_01 on test2(object_id,DATA_OBJECT_ID,OWNER,OBJECT_NAME);

create index ix_test3_01 on test3(object_id,DATA_OBJECT_ID,OWNER,OBJECT_NAME);

8.3.2 问题SQL

SELECT COUNT(*)

FROM TEST2 T2

WHERE T2.OBJECT_ID IN (SELECT T3.OBJECT_ID

                       FROM TEST3 T3

                       WHERE T3.DATA_OBJECT_ID<3000)

   OR T2.OWNER IN (SELECT T3.OWNER

                         FROM TEST3 T3

                         WHERE T3.OBJECT_NAME='V$SQL_PLAN')

   OR T2.DATA_OBJECT_ID IN (SELECT T3.DATA_OBJECT_ID

                            FROM TEST3 T3

                            WHERE T3.OBJECT_ID<3000);

8.3.3 SQL优化改写1

SELECT COUNT(*) FROM

(SELECT *

FROM TEST2 T2

WHERE T2.OBJECT_ID IN (SELECT T3.OBJECT_ID

                       FROM TEST3 T3

                       WHERE T3.DATA_OBJECT_ID<3000)

UNION

SELECT *

FROM TEST2 T2

WHERE T2.OWNER IN (SELECT T3.OWNER

                         FROM TEST3 T3

                         WHERE T3.OBJECT_NAME='V$SQL_PLAN')

UNION

SELECT *

FROM TEST2 T2

WHERE T2.DATA_OBJECT_ID IN (SELECT T3.DATA_OBJECT_ID

                            FROM TEST3 T3

                            WHERE T3.OBJECT_ID<3000));

性能反而下降了,主要原因是id 11,12用owner进行关联时,走了内连接,没走半连接,重复值太多,造成数据翻翻。

这里优化器改为内连接的原因是union有去重复的作用。

8.3.4 SQL优化改写2

SELECT COUNT(*) FROM (

SELECT DISTINCT TT.* FROM

(SELECT *

FROM TEST2 T2

WHERE T2.OBJECT_ID IN (SELECT T3.OBJECT_ID

                       FROM TEST3 T3

                       WHERE T3.DATA_OBJECT_ID<3000)

UNION ALL

SELECT *

FROM TEST2 T2

WHERE T2.OWNER IN (SELECT T3.OWNER

                         FROM TEST3 T3

                         WHERE T3.OBJECT_NAME='V$SQL_PLAN')

UNION ALL

SELECT *

FROM TEST2 T2

WHERE T2.DATA_OBJECT_ID IN (SELECT T3.DATA_OBJECT_ID

                            FROM TEST3 T3

                            WHERE T3.OBJECT_ID<3000)) TT);

虽然看着成本增加了,但是执行时间由100多秒下降到不到2秒。

猜你喜欢

转载自blog.csdn.net/songjian1104/article/details/91958098