我有一个customer_view,其中有6个字段
ID , Name , Email , First_Name , Last_Name , Status
。
每当我查询视图时,我总是查询名称和ID。
我是否应该仅使用字段ID和名称创建另一个自定义视图Customer_Custom_view?
这会以任何方式影响表现吗?
Select Id from users
where customer_id = (select id from customer_view where name ='XYZ');
Select Id from users
where customer_id = (select id from customer_custom_view where name = 'XYZ');
答案 0 :(得分:1)
我认为 Oracle优化器非常智能,可以转换查询并在两种情况下都使用最佳执行计划。因此,很可能根本没有任何区别。
为什么不测试它看看。
案例#1 现有观点
SQL> CREATE OR REPLACE VIEW emp_view AS SELECT empno, ename, deptno, JOB, sal, mgr FROM emp;
View created.
SQL>
SQL> EXPLAIN PLAN FOR
2 SELECT * FROM emp
3 where empno = (select empno from emp_view where ename='SCOTT');
Explained.
SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 587534197
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 37 | 6 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL | EMP | 1 | 37 | 3 (0)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| EMP | 1 | 10 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------
1 - filter("EMPNO"= (SELECT "EMPNO" FROM LALIT."EMP" "EMP" WHERE
"ENAME"='SCOTT'))
2 - filter("ENAME"='SCOTT')
16 rows selected.
SQL>
案例#2 自定义视图
SQL> CREATE OR REPLACE VIEW emp_custom_view AS SELECT empno, ename FROM emp;
View created.
SQL>
SQL> EXPLAIN PLAN FOR
2 SELECT * FROM emp
3 WHERE empno = (SELECT empno FROM emp_custom_view WHERE ename='SCOTT');
Explained.
SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 587534197
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 37 | 6 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL | EMP | 1 | 37 | 3 (0)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| EMP | 1 | 10 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------
1 - filter("EMPNO"= (SELECT "EMPNO" FROM LALIT."EMP" "EMP" WHERE
"ENAME"='SCOTT'))
2 - filter("ENAME"='SCOTT')
16 rows selected.
SQL>
CASE#1现有视图
SQL> CREATE OR REPLACE VIEW emp_view AS SELECT empno, ename, deptno, JOB, sal, mgr FROM emp;
View created.
SQL>
SQL> EXPLAIN PLAN FOR
2 SELECT * FROM emp
3 where empno = (select empno from emp_view where empno= 7369);
Explained.
SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------
Plan hash value: 4162864836
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 39 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 39 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | PK_EMP | 1 | | 0 (0)| 00:00:01 |
|* 3 | INDEX UNIQUE SCAN | PK_EMP | 1 | 4 | 0 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("EMPNO"= (SELECT "EMPNO" FROM SCOTT."EMP" "EMP" WHERE
"EMPNO"=7369))
3 - access("EMPNO"=7369)
17 rows selected.
SQL>
CASE#2自定义视图
SQL> CREATE OR REPLACE VIEW emp_custom_view AS SELECT empno, ename FROM emp;
View created.
SQL>
SQL> EXPLAIN PLAN FOR
2 SELECT * FROM emp
3 WHERE empno = (SELECT empno FROM emp_custom_view WHERE empno=7369);
Explained.
SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------
Plan hash value: 4162864836
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 39 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 39 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | PK_EMP | 1 | | 0 (0)| 00:00:01 |
|* 3 | INDEX UNIQUE SCAN | PK_EMP | 1 | 4 | 0 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("EMPNO"= (SELECT "EMPNO" FROM SCOTT."EMP" "EMP" WHERE
"EMPNO"=7369))
3 - access("EMPNO"=7369)
17 rows selected.
SQL>
因此,两种情况下的解释计划完全相同。
答案 1 :(得分:0)
根据在基础表上创建的索引,可能会有很大差异。
例如,如果您的桌面上只有CLUSTERED
索引,并且querying
只有name
和ID
列,则其他列为{{1}也是。根据其他列的类型,性能可以大幅提升。
现在,如果您创建一个read
非聚集索引,如下所示:
COVERING
并且您只查询CREATE INDEX IX_TEST ON [dbo].[TEST]
(
[ID] ASC
,[Name] ASC
)
和ID
列,SQL查询引擎将使用它。这将以任何方式减少IO操作。多少,取决于您的表的大小和其他列的类型。