针对组中顶级结果的SQL优化
我需要帮助优化查询的一部分,这部分查询的执行计划非常糟糕。表TB_供应商大约有500000行针对组中顶级结果的SQL优化,sql,oracle,Sql,Oracle,我需要帮助优化查询的一部分,这部分查询的执行计划非常糟糕。表TB_供应商大约有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
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_供应商的内容由视图提供,并且也有大约500000行。
你能给我推荐一种更有效的方法来获得完全相同的结果吗?
提前感谢感谢您的回答,我准备了一个测试用例:
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 |
| | | | |
我不明白下面的选择。您是否将表TB\U SUPPLIER t加入到t.supl\u id=v.corp\u id上的视图VW\u SUPPLIER v中,但也加入到t.supl\u id=某个不同的第一个值上?您能否先对视图进行排序,可能会减少所选列的数量,然后将其连接到TB_供应商?此外,您能否向我们展示一些示例数据,尤其是VW_供应商的示例数据?当您说“…最终的执行计划非常糟糕”如果您能提供这样的执行计划,那将非常有帮助。
DISTINCT
子句肯定是无用的。除此之外,WHERE T.SUPL\u ID=(选择SUP\u ID…WHERE CORP\u ID=T.SUPL\u ID…)
锁定有点奇怪。K.SUPL\u ID
不存在。