【问题标题】:Oracle SQL: most efficient way to perform filteringOracle SQL:执行过滤的最有效方式
【发布时间】:2015-04-16 21:57:27
【问题描述】:

当我开始在大表上编写 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

【问题讨论】:

  • 检查执行。计划,你会发现这三个语句都是一样的。如果没有,那么您在某个地方有问题。
  • @ibre5041 。 . .三个语句的执行计划不应该相同,因为第一个执行的操作与其他两个不同。
  • SQL 声明性语言。因此,如果两个语句具有相同的“含义”,那么它们也应该具有相同的 exec。计划。如果您在第一种情况下添加了约束,那么执行计划将是相同的。例如尝试添加唯一的,而不是 NULL 到过滤列。但我知道通常第一种情况是不同的 - 基数不同。

标签: sql oracle filter inner-join where


【解决方案1】:

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

让我们通过EMPDEPT 表的小例子来理解这一点。

查询 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>

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

【讨论】:

  • 顺便说一句,当连接是 1-n 而不是 n-1 时,这些查询可能会返回不同的结果,只需在子查询中交换 empdept。添加DISTINCT后,这种情况下的方案还是一样吗? EXISTS 也一样?
  • 在您的情况下,DEPT 表完全从 exec 中排除。计划。可能是因为 deptno 上的 FK?
  • 一个执行计划取决于许多参数(卷、索引、数据库配置)。因此,没有一个唯一的真理……您必须自己进行试验并选择适合您特定需求的解决方案。阅读 Tom Kyte 的书籍。
猜你喜欢
  • 2016-05-10
  • 2013-08-07
  • 2017-04-16
  • 2012-03-29
  • 1970-01-01
  • 1970-01-01
  • 2010-12-07
  • 1970-01-01
  • 2012-11-11
相关资源
最近更新 更多