Oracle 查询优化器 -- 改写查询语句

原创 2015年07月10日 17:17:25

-- Start

当我们执行一条查询语句的时候,我们只告诉 Oracle 我们想要哪些数据,至于数据在哪里,怎么找,那是查询优化器的事情,优化器需要改写查询语句,决定访问路径(如:全表扫描,快速全索引扫描,索引扫描),决定表联接顺序等。至于选择哪种方式,优化器需要根据数据字典做出判断。

那优化器如何改写查询语句呢?

第一种方法叫合并视图,如果你的查询语句中引用了视图,那么优化器会把视图合并到查询中,下面是一个简单的例子,需要注意的是优化器也不是神,如果你的视图包含集合操作符,聚合函数,Group by 等,优化器也傻了,不知道如何合并了。

-- 视图定义
CREATE VIEW employees_50_vw AS
	SELECT employee_id, last_name, job_id, salary, commission_pct, department_id
	FROM employees
	WHERE department_id = 50;

-- 查询语句
SELECT employee_id
FROM employees_50_vw
WHERE employee_id > 150;

-- 合并视图后的查询语句
SELECT employee_id
FROM employees
WHERE department_id = 50
AND employee_id > 150;

第二种方法叫谓词推进(Predicate Pushing),对于那些无法执行合并视图的查询语句,Oracle 会把查询语句中的条件挪到视图中,下面是一个简单的例子。

-- 视图定义
CREATE VIEW all_employees_vw AS
	(SELECT employee_id, last_name, job_id, commission_pct, department_id FROM employees)
	UNION
	(SELECT employee_id, last_name, job_id, commission_pct, department_id FROM contract_workers);

-- 查询语句的查询语句
SELECT last_name
FROM all_employees_vw
WHERE department_id = 50;

-- 谓词推进
SELECT last_name
FROM ( 
	SELECT employee_id, last_name, job_id, commission_pct, department_id FROM employees
		WHERE department_id=50 -- 注意此处
	UNION
	SELECT employee_id, last_name, job_id, commission_pct, department_id FROM contract_workers
		WHERE department_id=50 -- 注意此处
);

第三种方法是将非嵌套子查询转化为表连接。下面是一个简单的例子。需要注意的是,并不是所有的非嵌套子查询都能转化为表连接,对于下面的例子而言,如果 customers.cust_id 不是主键,转化后会产生笛卡尔集。

-- 非嵌套子查询
SELECT *
FROM sales
WHERE cust_id IN (SELECT cust_id FROM customers);

-- 表连接
SELECT sales.*
FROM sales, customers
WHERE sales.cust_id = customers.cust_id;

第四种方法是使用物化视图改写查询,物化视图是将一个查询的结果集保存在一个表中,如果你的查询语句和某个物化视图兼容,那么 Oracle 就可以直接从物化视图中取得数据。

--更多参见:Oracle SQL 优化精萃

-- 声明:转载请注明出处

-- Last edited on 2015-07-10

-- Created by ShangBo on 2015-07-10

-- End


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Oracle 查看执行计划

-- Start 我们可以通过 EXPLAIN PLAN 语句生成执行计划,该语句把执行计划保存到一个叫做 PLAN_TABLE 的表中,我们可以通过查询这个表来查看执行计划。下面是一个简单例子。 ...

Oracle SQL 优化精萃

-- Start -- 更多参见:Oracle  精萃 -- 声明:转载请注明出处 -- Last edited on 2015-06-29 -- Created by ShangBo o...

Oracle 查询耗时 SQL

-- Start 当你的系统变慢时,如何查询系统中最耗时的 SQL 呢?试一试下面的 SQL 吧。 select * from ( select * from V$SQLSTATS -- ...

查看Oracle最耗时的SQL

1.查看总消耗时间最多的前10条SQL语句 select *   from (select v.sql_id,                v.ch...

oracle中的相关子查询(correlated subqueries)

http://blog.163.com/wkyuyang_001/blog/static/10802122820091751358252/ oracle中的相关子查询(correlate...

Oracle 减少数据库访问次数

-- Start 连接数据库是非常耗时的,虽然应用程序会采用连接池技术,但与数据库交互依然很耗时,这就要求我们尽量用一条语句干完所有的事,尤其要避免把 SQL 语句写在循环中,如果你遇到这样的人...

Oracle 动态 SQL

-- Start 如果你还不知道什么是动态 SQL,请参考 PL/SQL 动态 SQL 如果有可能,尽量不要使用动态 SQL,动态 SQL需要运行时编译,影响性能。如果一定要使用动态 SQL...

Oracle--多表查询及子查询

多表查询 1、找涉及中的表 2、找表中的关联条件 3、要查询的东西查询出来  ps:n张表,至少要找n-1个关联条件,而且n-1关联条件之间是 and 内连接 查询出雇员的...

PL/SQL 动态 SQL

-- Start 什么是动态 SQL 呢?它是运行时才动态拼接和执行的 SQL。相对于静态 SQL,它最大的优势就是灵活,可以执行 DDL 语句。缺点是它没有经过预编译,运行时可能由于拼接错误、权限等...

Oracle连接查询,子查询(相关子查询,嵌套子查询)

1,Demo连接查询   --======================================================== --ylb:Oracle ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)