我有下面的oracle查询,它正在获取结果并以完美的方式显示结果,但请建议我能以更有效的方式编写以下查询
SELECT DISTINCT PSNETWORKID
FROM JGH
INNER JOIN IDF
ON IDF.PSIDFFIID = JGH.PSNETWORKID
WHERE (JGH.zzACQUIRERID IN
(SELECT DISTINCT pstdftermid FROM YUI WHERE pstdftermownid =111111
)
OR zzACQUIRERID = 111111);
答案 0 :(得分:0)
这似乎是您的查询:
select distinct PSNETWORKID
from JGH INNER JOIN
IDF
on IDF.PSIDFFIID = JGH.PSNETWORKID
where JGH.zzACQUIRERID in (select pstdftermid
from YUI
where pstdftermownid = 111111
) or
zzACQUIRERID = 111111;
首先,select distinct
通常是一个坏主意。让我假设它在其中一个表中是唯一的 - 比如JFH
。然后,我会这样做:
select jgh.PSNETWORKID
from JGH
where exists (select 1
from IDF
where IDF.PSIDFFIID = JGH.PSNETWORKID
) and
(exists (select 1
from YUI
where JGH.zzACQUIRERID = YUI.pstdftermid and YUI.pstdftermownid = 111111
) or
jgh.zzACQUIRERID = 111111
);
然后,我会建议IDF(PSIDFFIID)
和YUI(pstdftermid, pstdftermownid)
上的索引。
答案 1 :(得分:0)
“高效”是指简洁或更快的运行时间?通常你想使用EXIST而不是IN。
SELECT distinct PSNETWORKID
FROM JGH
INNER
JOIN IDF
ON IDF.PSIDFFIID= JGH.PSNETWORKID
WHERE EXISTS
( SELECT 1
FROM (SELECT pstdftermid conditionField
FROM YUI
UNION ALL
SELECT 111111 AS conditionField
FROM dual
) TMP
WHERE JGH.zzACQUIRERID = TMP.conditionField
);
答案 2 :(得分:0)
这是在Oracle 11.2.0.2.0上测试的。请注意,您的版本在此处是相关的,因为旧版本的某些非常好的建议可能与较新版本无关。
这是我使用您的查询和生成的数据执行的执行计划
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 39 | | 437 (1)| 00:00:06 |
| 1 | HASH UNIQUE | | 1 | 39 | | 437 (1)| 00:00:06 |
|* 2 | FILTER | | | | | | |
|* 3 | HASH JOIN | | 108K| 4142K| 2656K| 436 (1)| 00:00:06 |
| 4 | TABLE ACCESS FULL| IDF | 108K| 1380K| | 46 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL| JGH | 109K| 2786K| | 62 (2)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | PSTDFTERMID | 725 | 18850 | | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("JGH"."ZZACQUIRERID"=111111 OR EXISTS (SELECT 0 FROM "YUI" "YUI"
WHERE "PSTDFTERMOWNID"=111111 AND "PSTDFTERMID"=:B1))
3 - access("IDF"."PSIDFFIID"="JGH"."PSNETWORKID")
6 - access("PSTDFTERMID"=:B1 AND "PSTDFTERMOWNID"=111111)
因此,一个可能建议使您的查询更“有效”可能是重新排序OR谓词并将子查询放在第二位以避免执行子查询(如果谓词{{1 }} 是真的。 但如果您在上面的第2行看到zzACQUIRERID = 111111
,则 由Oracle为您完成。
接下来的建议是使用filter
而不是EXISTS
运算符。如果您查看IN
的第二部分,则情况也是如此 - 查询重写并使用filter
。
所以最重要的部分是(并且我认为这与你的查询相关,如果它永远不会结束 - 你没有提到)在EXISTS
上有索引。这为您提供了第6行的索引访问。
如果你在这个地方看到像
那样的东西YUI(pstdftermid, pstdftermownid)
这会导致执行效率低下,为每个|* 8 | TABLE ACCESS FULL | YUI | 10000 | 100 | 10000 |00:00:01.82 | 131K| | | |
8 - filter(("PSTDFTERMID"=:B1 AND "PSTDFTERMOWNID"=111111))
密钥进行一次全表扫描。
所以我的建议是在第一步检查执行计划,并确保有提到的索引。
仅当您希望强制 Oracle采用不同的执行计划时才重写查询,而不是基于过去版本中的最佳实践。