【SQL优化器查询变换器】视图合并(View Merging)

简介:

(基于成本的优化器组件)
 
查询变换器
  被解析器解析过的查询语句进入查询变换器,表现出来的是一组查询块(query block),
这些查询块之间是相互关联的或者是嵌套的,查询的形式决定这些查询块相互之间如何被关联。查询变换器的主要目的就是决定改变查询的形式是否有利于产生一个好的执行计划。查询变换器使用四种不同的查询变换技术:
1- 视图合并(View Merging)
2- 谓词推进(Predicate Pushing)
3- 非嵌套子查询(Subquery Unnesting)
4- 物化视图的查询重写(Query Rewrite with Materialized Views)

最终应用于查询的也可以是以上四种变换技术的任意组合。
 
视图合并
  查询中的每个视图都会被解析器扩展到一个独立的查询块中,这个查询块本质上是用来描述视图定义的,是视图的结果。优化器的一个任务就是去分析这个独立视图查询块(view query block)并产生一个视图子计划(subplan),然后优化器在产生整个查询执行计划的同时使用视图子计划来处理剩余的查询部分。由于视图是被独立在整个查询之外被优化的,因此这种技术常常会导致一个不良执行计划的产生。
    查询变换器通过将视图查询块合并到查询块中从而消除这种不良执行计划。绝大多数类型的视图是可以被合并的。在一个视图被合并后,它原有的视图查询块被包含到查询块中,也就是说视图查询块不存在了,因此也不再需要产生一个子计划。 
SQL> create view v_emp as
  2  select a.* ,b.dname ,b.loc from scott.emp a ,scott.dept b
  3  where a.deptno = b.deptno
  4  and b.deptno =20;

View created.

Elapsed: 00:00:00.13

SQL> set autot traceonly exp
SQL> set linesize 999
SQL> select a.empno from v_emp a where a.empno >1000;
Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 2122483104

----------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |     5 |    50 |     2   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                |         |     5 |    50 |     2   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN          | PK_DEPT |     1 |     3 |     0   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS BY INDEX ROWID| EMP     |     5 |    35 |     2   (0)| 00:00:01 |
|*  4 |    INDEX RANGE SCAN          | PK_EMP  |    14 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

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

   2 - access("B"."DEPTNO"=20)
   3 - filter("A"."DEPTNO"=20)
   4 - access("A"."EMPNO">1000)

----可以看出上述计划发生了视图合并。关于视图的执行计划和下面的是等价的。
SQL> select a.* ,b.dname,b.loc from scott.emp a,scott.dept b
  2  where a.deptno = b.deptno
  3  and b.deptno =20
  4  and a.empno >1000;
Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 3257024035

----------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |     5 |   285 |     3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                |         |     5 |   285 |     3   (0)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    20 |     1   (0)| 00:00:01 |
|*  3 |    INDEX UNIQUE SCAN         | PK_DEPT |     1 |       |     0   (0)| 00:00:01 |
|*  4 |   TABLE ACCESS BY INDEX ROWID| EMP     |     5 |   185 |     2   (0)| 00:00:01 |
|*  5 |    INDEX RANGE SCAN          | PK_EMP  |    14 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

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

   3 - access("B"."DEPTNO"=20)
   4 - filter("A"."DEPTNO"=20)
   5 - access("A"."EMPNO">1000)

相关文章
|
14天前
|
SQL 监控 关系型数据库
SQL语句当前及历史信息查询-performance schema的使用
本文介绍了如何使用MySQL的Performance Schema来获取SQL语句的当前和历史执行信息。Performance Schema默认在MySQL 8.0中启用,可以通过查询相关表来获取详细的SQL执行信息,包括当前执行的SQL、历史执行记录和统计汇总信息,从而快速定位和解决性能瓶颈。
|
25天前
|
SQL 存储 缓存
如何优化SQL查询性能?
【10月更文挑战第28天】如何优化SQL查询性能?
82 10
|
19天前
|
SQL 关系型数据库 MySQL
|
2月前
|
SQL 数据库 开发者
功能发布-自定义SQL查询
本期主要为大家介绍ClkLog九月上线的新功能-自定义SQL查询。
|
2月前
|
SQL 移动开发 Oracle
SQL语句实现查询连续六天数据的方法与技巧
在数据库查询中,有时需要筛选出符合特定时间连续性条件的数据记录
|
2月前
|
SQL Java 数据库连接
如何使用`DriverManager.getConnection()`连接数据库,并利用`PreparedStatement`执行参数化查询,有效防止SQL注入。
【10月更文挑战第6天】在代码与逻辑交织的世界中,我从一名数据库新手出发,通过不断探索与实践,最终成为熟练掌握JDBC的开发者。这段旅程充满挑战与惊喜,从建立数据库连接到执行SQL语句,再到理解事务管理和批处理等高级功能,每一步都让我对JDBC有了更深的认识。示例代码展示了如何使用`DriverManager.getConnection()`连接数据库,并利用`PreparedStatement`执行参数化查询,有效防止SQL注入。
103 5
|
2月前
|
SQL 数据挖掘 数据库
SQL查询每秒的数据:技巧、方法与性能优化
id="">SQL查询功能详解 SQL(Structured Query Language,结构化查询语言)是一种专门用于与数据库进行沟通和操作的语言
|
2月前
|
SQL 移动开发 大数据
SQL语句查询连续六天满足条件的记录
在数据库管理和数据分析中,我们经常需要查询符合特定时间范围内连续几天的记录
|
29天前
|
SQL 关系型数据库 MySQL
mysql编写sql脚本:要求表没有主键,但是想查询没有相同值的时候才进行插入
mysql编写sql脚本:要求表没有主键,但是想查询没有相同值的时候才进行插入
31 0
|
2月前
|
SQL 数据可视化 BI
SQL语句及查询结果解析:技巧与方法
在数据库管理和数据分析中,SQL语句扮演着至关重要的角色