我要改进此查询:
SELECT sub.SDDOCO
FROM(
SELECT SDSHAN, SDDOCO, SDMCU, SDLITM, SDIR03, SDVR01
FROM PRODDTA.F4211
UNION ALL
SELECT SDSHAN, SDDOCO, SDMCU, SDLITM, SDIR03, SDVR01
FROM PRODDTA.F42119
)sub
INNER JOIN PRODDTA.F0101 tab
ON sub.SDSHAN = tab.ABAN8
WHERE
sub.SDMCU LIKE CONCAT(CONCAT('%',nvl(:pMCU,SDMCU)),'%')
AND sub.SDLITM LIKE CONCAT(CONCAT('%',nvl(:pLITM,SDLITM)),'%')
AND sub.SDIR03 LIKE CONCAT(CONCAT('%',nvl(:pIR03,SDIR03)),'%')
AND tab.ABALKY LIKE CONCAT(CONCAT('%',nvl(:pALKY,ABALKY)),'%')
AND sub.SDVR01 LIKE CONCAT(CONCAT('%',nvl(:pVR01,SDVR01)),'%')
我已经以这种方式修改了WHERE条件:
((:pMCU IS NOT NULL AND sub.SDMCU LIKE '%' || :pMCU || '%') OR :pMCU IS NULL)
AND ((:pLITM IS NOT NULL AND sub.SDLITM LIKE '%' || :pLITM || '%') OR :pLITM IS NULL)
AND ((:pIR03 IS NOT NULL AND sub.SDIR03 LIKE '%' || :pIR03 || '%') OR :pIR03 IS NULL)
AND ((:pVR01 IS NOT NULL AND sub.SDVR01 LIKE '%' || :pVR01 || '%') OR :pVR01 IS NULL)
AND ((:pALKY IS NOT NULL AND tab.ABALKY LIKE '%' || :pALKY || '%') OR :pALKY IS NULL)
在this link,您可以阅读两个查询的执行计划。 哪一个更好? 有什么改进查询的建议吗? 我需要有结果的所有记录
修改: 哪里" F4211" table有71,758条记录,F42119有4,606,154条记录
编辑:和F0101表有634,187条记录。 Whith所有参数都设置为NULL,结果是在不合理的时间(几分钟)内有4,677,925条记录。 没有where子句的查询在58秒内占用4,677,925条记录
修改: 插入代码片段我超过了char的最大数量:( 有关发布执行计划的任何建议吗?
修改: 这是执行计划:
"PLAN_TABLE_OUTPUT"
"Plan hash value: 3925457500"
" "
"-----------------------------------------------------------------------------------------------------------"
"| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |"
"-----------------------------------------------------------------------------------------------------------"
"| 0 | SELECT STATEMENT | | 2 | 1224 | 614K (1)| 00:00:24 |"
"| 1 | NESTED LOOPS | | 2 | 1224 | 614K (1)| 00:00:24 |"
"| 2 | VIEW | index$_join$_004 | 31721 | 1455K| 11379 (1)| 00:00:01 |"
"|* 3 | HASH JOIN | | | | | |"
"| 4 | INDEX FAST FULL SCAN | F0101_0 | 31721 | 1455K| 2414 (1)| 00:00:01 |"
"|* 5 | INDEX FAST FULL SCAN | F0101_3 | 31721 | 1455K| 8390 (1)| 00:00:01 |"
"| 6 | VIEW | | 1 | 565 | 19 (0)| 00:00:01 |"
"| 7 | UNION ALL PUSHED PREDICATE | | | | | |"
"|* 8 | TABLE ACCESS BY INDEX ROWID BATCHED| F4211 | 1 | 417 | 9 (0)| 00:00:01 |"
"|* 9 | INDEX RANGE SCAN | F4211_4 | 6 | | 3 (0)| 00:00:01 |"
"|* 10 | TABLE ACCESS BY INDEX ROWID BATCHED| F42119 | 1 | 422 | 10 (0)| 00:00:01 |"
"|* 11 | INDEX RANGE SCAN | F42119_9 | 10 | | 3 (0)| 00:00:01 |"
"-----------------------------------------------------------------------------------------------------------"
" "
"Predicate Information (identified by operation id):"
"---------------------------------------------------"
" "
" 3 - access(ROWID=ROWID)"
" 5 - filter(""GGG"".""ABALKY"" LIKE U'%'||NVL(:PALKY,""GGG"".""ABALKY"")||U'%')"
" 8 - filter(""SDMCU"" LIKE U'%'||NVL(:PMCU,""SDMCU"")||U'%' AND ""SDLITM"" LIKE "
" U'%'||NVL(:PLITM,""SDLITM"")||U'%' AND ""SDIR03"" LIKE U'%'||NVL(:PIR03,""SDIR03"")||U'%' AND ""SDVR01"" "
" LIKE U'%'||NVL(:PVR01,""SDVR01"")||U'%')"
" 9 - access(""SDSHAN""=""GGG"".""ABAN8"")"
" 10 - filter(""SDMCU"" LIKE U'%'||NVL(:PMCU,""SDMCU"")||U'%' AND ""SDLITM"" LIKE "
" U'%'||NVL(:PLITM,""SDLITM"")||U'%' AND ""SDIR03"" LIKE U'%'||NVL(:PIR03,""SDIR03"")||U'%' AND ""SDVR01"" "
" LIKE U'%'||NVL(:PVR01,""SDVR01"")||U'%')"
" 11 - access(""SDSHAN""=""GGG"".""ABAN8"")"
答案 0 :(得分:1)
1 Oracle具有提高查询性能的良好工具,例如DBMS_SQLTUNE https://docs.oracle.com/database/121/TGSQL/tgsql_sqltune.htm#TGSQL586 在开始时,您可以创建调整任务
declare
l_task_name varchar2(4000);
begin
l_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
sql_text => q'!SELECT sub.SDDOCO
FROM(
SELECT SDSHAN, SDDOCO, SDMCU, SDLITM, SDIR03, SDVR01
FROM PRODDTA.F4211
UNION ALL
SELECT SDSHAN, SDDOCO, SDMCU, SDLITM, SDIR03, SDVR01
FROM PRODDTA.F42119
)sub
INNER JOIN PRODDTA.F0101 tab
ON sub.SDSHAN = tab.ABAN8
WHERE
sub.SDMCU LIKE CONCAT(CONCAT('%',nvl(:pMCU,SDMCU)),'%')
AND sub.SDLITM LIKE CONCAT(CONCAT('%',nvl(:pLITM,SDLITM)),'%')
AND sub.SDIR03 LIKE CONCAT(CONCAT('%',nvl(:pIR03,SDIR03)),'%')
AND tab.ABALKY LIKE CONCAT(CONCAT('%',nvl(:pALKY,ABALKY)),'%')
AND sub.SDVR01 LIKE CONCAT(CONCAT('%',nvl(:pVR01,SDVR01)),'%')!'
, bind_list => sql_binds( anydata.ConvertVarchar2('ABC'),
anydata.ConvertVarchar2('BCD'),
anydata.ConvertVarchar2('CDE'),
anydata.ConvertVarchar2('DEF'),
anydata.ConvertVarchar2('EFG'))
, task_name => 'TEST_TUNING_SQL_SO'
, description => 'Task to tune a query from StackOverflow');
end;
/
执行后
begin
DBMS_SQLTUNE.EXECUTE_TUNING_TASK (
task_name => 'TEST_TUNING_SQL_SO');
end;
/
检索报告并执行建议
select DBMS_SQLTUNE.REPORT_TUNING_TASK(
task_name => 'TEST_TUNING_SQL_SO') from dual;
2如何公布计划
您可以以文本格式(而非HTML格式)生成它。并尝试仅添加包含谓词信息的计划表。如果不需要,您可以排除任何其他信息。