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 中,优化器 足够智能以完成其工作。所以没关系,您的两个查询都将在内部进行优化以有效地完成任务。优化器可能会执行 查询重写 并选择 高效执行计划 。
让我们用 EMP
和 DEPT
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>
因此,无论您以不同的方式编写查询,优化器都会选择最有效的执行计划。除非你强制优化器使用提示等选择不同的计划。你总是会看到有执行使用相同的计划。
当我开始在大表上编写 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 中,优化器 足够智能以完成其工作。所以没关系,您的两个查询都将在内部进行优化以有效地完成任务。优化器可能会执行 查询重写 并选择 高效执行计划 。
让我们用 EMP
和 DEPT
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>
因此,无论您以不同的方式编写查询,优化器都会选择最有效的执行计划。除非你强制优化器使用提示等选择不同的计划。你总是会看到有执行使用相同的计划。