0

SQL> desc emp_1;

Name     Type         Nullable Default Comments 
-------- ------------ -------- ------- -------- 
EMP_ID   NUMBER                                 
EMP_NAME VARCHAR2(20) Y                         
DEPTNO   NUMBER(10)   Y

SQL> 描述部门

Name      Type         Nullable Default Comments 
--------- ------------ -------- ------- -------- 
DEPT_ID   NUMBER       Y                         
DEPT_NAME VARCHAR2(20) Y 

SQL> 创建索引 abc_idex ON emp_1 (deptno);

Index created

select /*+ index(emp_1 abc_idex) */ emp_name from emp_1 INNER JOIN dept ON emp_1.deptno = dept.dept_id

Explain Plan :- 
SELECT STATEMENT, GOAL = ALL_ROWS           271 100000  800000
 MERGE JOIN         271 100000  800000
  TABLE ACCESS BY INDEX ROWID   EXAMINBI    EMP_1   267 100000  500000
   INDEX FULL SCAN  EXAMINBI    ABC_IDEX    131 100000  
  SORT JOIN         4   4   12
   TABLE ACCESS FULL    EXAMINBI    DEPT    3   4   12

select /*+ index(emp_1 abc_idex) */ emp_name from emp_1 INNER JOIN dept ON emp_1.deptno = dept.dept_id 和 emp_1.emp_name=dept.dept_name

Explain Plan:- 
SELECT STATEMENT, GOAL = ALL_ROWS           272 1   11
 HASH JOIN          272 1   11
  TABLE ACCESS FULL EXAMINBI    DEPT    3   4   24
  TABLE ACCESS BY INDEX ROWID   EXAMINBI    EMP_1   267 100000  500000
   INDEX FULL SCAN  EXAMINBI    ABC_IDEX    131 100000  

在您的帮助下,我正在清除我的索引概念。我的理解是,oracle 将跳过我的索引提示,因为它需要其他未索引的列(emp_name),但在第二种情况下,emp_1 表仍被索引扫描。我的问题在这种情况下是否会有所帮助,我使用另一列进行不使用索引的连接(在我们的示例 emp_name 中)?在这种情况下我们应该使用索引提示吗?*注意:- 我知道这是 emp_name 和 dept_name 不是逻辑连接,但只是为了测试目的,我创建了相同的。*

4

3 回答 3

1

我想知道它是否建议在加入时使用索引提示,您正在使用来自同一个表的非索引列。会有帮助吗?

大多数情况下

一般情况下你根本不使用提示。正如您在此处看到的,您使用了一个提示,Oracle 已经遵循它并做了一些愚蠢的事情。您仅在非常有限的情况下使用提示,通常仅当您了解 Oracle 无法自行解决的数据的性质时。一般来说,我使用的唯一提示是基数提示,因为 Oracle 有时真的无法正确计算出基数。

不要假设您需要经常使用提示。你没有。即使提示现在有效,但当数据的性质发生变化时,它可能会停止工作。

于 2012-11-28T10:59:06.297 回答
0

在您的情况下,使用 index 可能会减慢整个语句的速度。这是因为您正在查询整个表 DEPT 和 EMP_1。由于提示,Oracle 必须同时查询全表和索引。你真的想要这个吗?

在像这样的简单情况下,我更喜欢不使用提示。优化器做得很好。

如果您使用特定部门的声明,那么结果会更好

select emp_name
  from emp_1 INNER JOIN dept ON emp_1.deptno = dept.dept_id
  where dept.dname = 'any department'
于 2012-11-28T08:52:38.520 回答
0

所以:

select /*+ cardinality(0)*/ emp_name 
from emp_1 
   INNER JOIN dept ON emp_1.deptno = dept.dept_id
于 2012-11-28T08:56:36.643 回答