smw*_*ody 5 oracle join oracle-10g plsql
我面临着一种我无法理解和克服的情况。
简而言之,我们有左连接查询,如:
select from a
left join b on a.key1=b.key1 or a.key1=b.key2
Run Code Online (Sandbox Code Playgroud)
这工作非常缓慢,同时两者分开:
select from a
left join b on a.key1=b.key1
select from a
left join b on a.key1=b.key2
Run Code Online (Sandbox Code Playgroud)
工作非常快。
b.key1 有正常索引
b.key2 有正常索引
我无法理解这种行为的原因?我的连接策略或索引使用中是否缺少一些非常基本的东西?
在这里,我们有详细的计划:
无或(TOP_USTR_ADMIN_IP - ustrip 列的索引名称):
SQL> explain plan for
SELECT * FROM top.macs_constraint mc
LEFT JOIN top.top_ustr tu ON tu.ustrip = mc.IP;
Explained.
SQL> SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
Plan hash value: 349751289
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 22 | 1296 (1)| 00:00:16 |
| 1 | SORT AGGREGATE | | 1 | 22 | | |
|* 2 | HASH JOIN RIGHT OUTER| | 981K| 20M| 1296 (1)| 00:00:16 |
|* 3 | INDEX FAST FULL SCAN| TOP_USTR_ADMIN_IP | 23187 | 181K| 62 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | MACS_CONSTRAINT | 629K| 8601K| 1231 (1)| 00:00:15 |
--------------------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("TU"."USTRIP"(+)="MC"."IP")
3 - filter("TU"."USTRIP"(+) IS NOT NULL)
Run Code Online (Sandbox Code Playgroud)
与或:
explain plan for
SELECT count(*) FROM top.macs_constraint mc
LEFT JOIN top.top_ustr tu ON (tu.ustrip = mc.IP or tu.skladIP = mc.IP);
Explained.
SQL> SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2704565128
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 14 | 322M (1)|999:59:59 |
| 1 | SORT AGGREGATE | | 1 | 14 | | |
| 2 | NESTED LOOPS OUTER | | 1887K| 25M| 322M (1)|999:59:59 |
| 3 | TABLE ACCESS FULL | MACS_CONSTRAINT | 629K| 8601K| 1231 (1)| 00:00:15 |
| 4 | VIEW | | 3 | | 513 (1)| 00:00:07 |
|* 5 | TABLE ACCESS FULL| TOP_USTR | 3 | 72 | 513 (1)| 00:00:07 |
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - filter("TU"."SKLADIP" IS NOT NULL AND "TU"."SKLADIP"="MC"."IP" OR
"TU"."USTRIP" IS NOT NULL AND "TU"."USTRIP"="MC"."IP")
Run Code Online (Sandbox Code Playgroud)
为什么or
在谓词中使用 using给出嵌套循环而没有使用索引?是否可以强制使用索引?
更新: “没有或”的错误附加错误计划。已修复
小智 6
OR 速度较慢,因为您不再可以执行索引查找,但会有效地强制数据库引擎查找索引树中的每个叶节点。使用单个参数(无 OR),引擎可以通过索引向下查找相关叶节点,但是当您向它询问 OR 时,它会扫描叶节点的整个范围。
如果性能太慢而无法容忍,请按照注释建议进行操作,并尝试 UNION(无重复值)或 UNION ALL(允许重复值),甚至单独两个单独的查询,然后在代码中将结果连接在一起层接收结果。
归档时间: |
|
查看次数: |
4700 次 |
最近记录: |