我需要帮助优化查询的一部分,该查询最终会导致错误的执行计划。表TB_SUPPLIER大约有500000行
SELECT K.supl_id
FROM TB_SUPPLIER T
WHERE T.SUPL_ID =
(
SELECT DISTINCT
FIRST_VALUE(SUP_ID) OVER(ORDER BY SUP_AVOB DESC NULLS LAST)
FROM VW_SUPPLIER
WHERE CORP_ID = T.SUPL_ID
AND SUP_ACTIVE = 1
);
不幸的是,内部VW_SUPPLIER的内容是由视图提供的,并且也有大约500000行。 您能推荐我一种更有效的方法来获得完全相同的结果吗? 预先感谢
答案 0 :(得分:0)
感谢您的回答,这里我准备了一个测试用例:
CREATE TABLE TB_CS
( SUPL_ID number (8,0) not null,
CS_TYPE varchar2(10 char),
CS_DEL number (1,0),
constraint c_pk primary key (SUPL_ID) using index
) ;
Insert into TB_CS (SUPL_ID,CS_TYPE,CS_DEL) values (35263391, 'C' , 0);
Insert into TB_CS (SUPL_ID,CS_TYPE,CS_DEL) values (35298444, 'C' , 0);
Insert into TB_CS (SUPL_ID,CS_TYPE,CS_DEL) values (35414837, 'C' , 0);
CREATE TABLE TB_SUPPLIER
( SUPL_ID number (8,0) not null,
constraint s_pk primary key(SUPL_ID) using index
);
Insert into TB_SUPPLIER (SUPL_ID) values (35263391);
Insert into TB_SUPPLIER (SUPL_ID) values (35298444);
Insert into TB_SUPPLIER (SUPL_ID) values (35414837);
create index IX_CS on TB_CS ( CS_DEL, CS_TYPE, SUPL_ID ) ;
ALTER TABLE TB_SUPPLIER ADD CONSTRAINT TB_CS_FK FOREIGN KEY ( supl_id ) REFERENCES TB_CS ( supl_id );
CREATE TABLE VW_SUPPLIER
( SUP_ID NUMBER(8,0) primary key,
CORP_ID NUMBER(8,0),
SUP_AVOB NUMBER,
SUP_ACTIVE NUMBER(1,0)
) ;
Insert into VW_SUPPLIER (SUP_ID,CORP_ID,SUP_AVOB,SUP_ACTIVE) values ('35355998','35298444','6715','1');
Insert into VW_SUPPLIER (SUP_ID,CORP_ID,SUP_AVOB,SUP_ACTIVE) values ('35358149','35298444','6390','1');
Insert into VW_SUPPLIER (SUP_ID,CORP_ID,SUP_AVOB,SUP_ACTIVE) values ('35532593','35298444','68','1');
Insert into VW_SUPPLIER (SUP_ID,CORP_ID,SUP_AVOB,SUP_ACTIVE) values ('35249072','35414837','66','1');
Insert into VW_SUPPLIER (SUP_ID,CORP_ID,SUP_AVOB,SUP_ACTIVE) values ('35300318','35414837','32','1');
Insert into VW_SUPPLIER (SUP_ID,CORP_ID,SUP_AVOB,SUP_ACTIVE) values ('35298289','35298444',null,'1');
Insert into VW_SUPPLIER (SUP_ID,CORP_ID,SUP_AVOB,SUP_ACTIVE) values ('35578515','35263391',null,'1');
Insert into VW_SUPPLIER (SUP_ID,CORP_ID,SUP_AVOB,SUP_ACTIVE) values ('35274495','35263391',null,'1');
这又是问题查询:
SELECT T.supl_id, V.*
FROM TB_SUPPLIER T
JOIN TB_CS C ON T.SUPL_ID = C.SUPL_ID
LEFT JOIN VW_SUPPLIER V ON V.CORP_ID = T.SUPL_ID
WHERE C.CS_DEL = 0 AND C.CS_TYPE IN ('C','S') and
V.SUP_ID = (
SELECT DISTINCT -- could not removed because of the single-row subquery returns more than one row
FIRST_VALUE(SUP_ID) OVER(ORDER BY SUP_AVOB DESC NULLS LAST)
FROM VW_SUPPLIER
WHERE CORP_ID = T.SUPL_ID
AND SUP_ACTIVE = 1
);
..这是预期的结果:
"SUP_ID", "CORP_ID","SUP_AVOB","SUP_ACTIVE"
35355998, 35298444, 6715, 1
35249072, 35414837, 66, 1
35274495, 35263391, null, 1
真实系统的执行计划如下
-------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 39 | 25M (11)| 00:16:41 |
| 1 | WINDOW BUFFER | | 1 | 39 | 25M (11)| 00:16:41 |
|* 2 | FILTER | | | | | |
| 3 | NESTED LOOPS | | 221K| 8427K| 12M (9)| 00:08:23 |
| 4 | NESTED LOOPS | | 221K| 7130K| 75 (4)| 00:00:01 |
| 5 | INLIST ITERATOR |
| | | | |