SQL优化组中的最佳结果

时间:2018-07-02 08:59:16

标签: sql oracle

我需要帮助优化查询的一部分,该查询最终会导致错误的执行计划。表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行。 您能推荐我一种更有效的方法来获得完全相同的结果吗? 预先感谢

1 个答案:

答案 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                               |

                            |       |       |            |          |