Oracle SQL:执行过滤的最有效方式

Oracle SQL: most efficient way to perform filtering

当我开始在大表上编写 SQL 查询时,我想知道哪个是最有效的。对我来说,它们看起来都一样。寻找 SQL 如何分解和执行这些查询的解释

选项 1:

select a.*
from table_a a
where a.column in (select filter from table_b)

选项 2:

select a.*
from table_a a, table_b b
where a.column=b.filter

选项 3:

select a.*
from table_a a
inner join table_b b
on a.column=b.filter

在最新版本的 Oracle 中,优化器 足够智能以完成其工作。所以没关系,您的两个查询都将在内部进行优化以有效地完成任务。优化器可能会执行 查询重写 并选择 高效执行计划

让我们用 EMPDEPT table 的小例子来理解这一点。

查询 1 :

SQL> explain plan for
  2  select a.*
  3  from emp a
  4  WHERE A.deptno IN (SELECT deptno FROM dept);

Explained.

SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------
Plan hash value: 3956160932

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    14 |   546 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| EMP  |    14 |   546 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------

   1 - filter("A"."DEPTNO" IS NOT NULL)

13 rows selected.

SQL>

查询 2 :

SQL> explain plan for
  2  SELECT A.*
  3  FROM emp A, dept b
  4  where a.deptno=b.deptno;

Explained.

SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------
Plan hash value: 3956160932

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    14 |   546 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| EMP  |    14 |   546 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------

   1 - filter("A"."DEPTNO" IS NOT NULL)

13 rows selected.

SQL>

查询 3 :

SQL> explain plan for
  2  select a.*
  3  from emp a
  4  INNER JOIN dept b
  5  ON A.deptno=b.deptno;

Explained.

SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------
Plan hash value: 3956160932

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    14 |   546 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| EMP  |    14 |   546 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------

   1 - filter("A"."DEPTNO" IS NOT NULL)

13 rows selected.

SQL>

因此,无论您以不同的方式编写查询,优化器都会选择最有效的执行计划。除非你强制优化器使用提示等选择不同的计划。你总是会看到有执行使用相同的计划。