`

将SQL优化做到极致 - 子查询优化

sql 
阅读更多
摘要: 编辑手记:子查询是SQL中比较重要的一种语法,恰当地应用会很大程度上提高SQL的性能,若用的不得当,也可能会带来很多问题。因此子查询也是SQL比较难优化的部分。今天一起来学习最常见的几种优化子查询到方式。
编辑手记:子查询是SQL中比较重要的一种语法,恰当地应用会很大程度上提高SQL的性能,若用的不得当,也可能会带来很多问题。因此子查询也是SQL比较难优化的部分。今天一起来学习最常见的几种优化子查询到方式。
作者简介:
韩锋
640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1
精通包括Oracle、MySQL、informix等多种关系型数据库,有丰富的数据库架构设计开发经验。就职于宜信。
针对子查询,优化器支持了多种优化策略。Oracle查询转换功能主要有启发式(基于规则)查询转换以及基于Cost的查询转换两种,针对子查询主要有Subquery Unnest、Push Subquery等。查询转换的目的是转化为Join(包括Semi、Anti Join等),充分利用索引、Join技术等高效访问方式提高效率。如果子查询不能unnest(启发式),可以选择把子查询转换为Inline View(基于Cost);如果都不可以,那么子查询就会最后执行,可能会看到类似Filter的操作。
1.子查询转换
下面先通过一个示例看看。
640?wx_fmt=png&wxfrom=5&wx_lazy=1
//上面代码准备了必要的数据环境,并收集相关对象的统计信息
640?wx_fmt=png&wxfrom=5&wx_lazy=1
//默认情况下,是将上面的操作转换为表间关联方式执行
640?wx_fmt=png&wxfrom=5&wx_lazy=1
/*通过提示no_unnest,禁止了子查询解嵌套。一次采用了原始的方式执行,子查询部分的作用就是"FILTER"*/
2.子查询合并
子查询合并是指优化器不再单独为子查询生成执行计划,而是将子查询合并到主查询中,最终为合并后的结果生成一个最优的执行计划。可以通过参数_simple_view_merging或者提示MERGE/NO_MERGE来控制是否开启、关闭子查询合并。
根据子查询的复杂程度,子查询可分为简单子查询、复杂子查询。
所谓简单子查询,是指可以简单将子查询字段投影到外部的情况。对于这种情况,优化器采取的是启发式策略,即满足条件下就行合并。
复杂子查询是指存在分组行数的情况。针对这种情况,优化器采取的是基于代价的策略,最终是否转换取决于成本。当然还有一些子查询是无法进行合并的。
下面通过几个示例看一下。
640?wx_fmt=png&wxfrom=5&wx_lazy=1
//这种方式下,并没有进行子查询合并。
下面强制看看效果
640?wx_fmt=png&wxfrom=5&wx_lazy=1
/*这里可以看到,没有再生成内联视图,子查询被合并了。那为什么默认没有进行子查询合并呢?从成本可见,显然不合并的成本更低*/
3.解嵌套子查询
解嵌套子查询是指在对存在嵌套子查询的复杂语句进行优化时,查询转换器会尝试将子查询展开,使得其中的表能与主查询中的表关联,从而获得更优的执行计划。部分子查询反嵌套属于启发式查询转换,部分属于基于代价的转换。
系统中存在一个参数来控制解嵌套子查询—_unnest_subquery。参数_unnest_subquery在8i中的默认设置是false,从9i开始其默认设置是true。然而9i在非嵌套时不考虑成本。只有在10g中才开始考虑两种不同选择的成本,并选取成本较低的方式。当从8i升级到9i时,可能想阻塞某些查询的非嵌套。利用子查询中的no_unnest提示可以完成这一点。在8i和9i中,如果star_transformation_enabled=true,则非嵌套时被禁用(即使用了提示)。在11g环境下还受优化器参数_optimizer_unnest_all_subqueries控制。此外,提示UNNEST/NO_UNNEST可以控制是否进行解嵌套。
下面我们通过几个示例看看解嵌套子查询。
1)IN/EXISTS转换为SEMI JOIN:
640?wx_fmt=png&wxfrom=5&wx_lazy=1
/*示例中的子查询引用表DEPT,最终转换为两个表的哈希半连接。也就是说,exists子句中的子查询被展开,其中的对象与主查询中的对象直接进行半关联操作*/
// IN的情况类似,如下:
640?wx_fmt=png&wxfrom=5&wx_lazy=1
2)IN/EXISTS转换为ANTI JOIN:
640?wx_fmt=png&wxfrom=5&wx_lazy=1
/*优化器将NOT EXISTS后的子查询做解嵌套,然后选择了哈希的反连接。这种转换属于基于代价的查询转换。*/
//下面看看NOT IN的情况
640?wx_fmt=png&wxfrom=5&wx_lazy=1
/*和NOT EXISTS类似,也选择了哈希连接,只不过是HASH JOIN ANTI NA。这里的NA,实际表示Null-Aware的意思,在11g及以后的版本中,Oracle增加了对空值敏感的反关联的支持*/
3)关联子查询的解嵌套
在对于关联子查询的解嵌套过程中,会将子查询构造出一个内联视图,并将内联视图与主查询的表进行关联。这个操作可以通过参数_unnest_subquery来控制。这种转换属于启发式查询转换。
640?wx_fmt=png&wxfrom=5&wx_lazy=1
/*在ID=2的步骤中生成了内联视图,然后跟外部表进行的哈希连接。下面尝试修改参数,看优化器如何处理*/
640?wx_fmt=png&wxfrom=5&wx_lazy=1
//这里转换成了嵌套循环的一种特列FILTER
4.子查询推进
子查询推进是一项对未能合并或者反嵌套的子查询优化的补充优化技术。这一技术是在9.2版本引入的。通常情况下,未能合并或者反嵌套的子查询的子计划会被放置在整个查询计划的最后执行,而子查询推进使得子查询能够提前被评估,使之可以出现在整体执行计划较早的步骤中,从而获得更优的执行计划。可以通过PUSH_SUBQ/NO_PUSH_SUBQ来控制。
640?wx_fmt=png&wxfrom=5&wx_lazy=1
//默认情况下,就是用子查询推进技术。
对比一下,我们看看强制不使用的情况
640?wx_fmt=png&wxfrom=5&wx_lazy=1
/*对比上面,对了一步FILTER。这里使用了嵌套循环,每一个EMP表的记录,都对应一次子查询的查询,获得MAX值*/
5.子查询分解
所谓子查询分解,是指由WITH创建的复杂查询语句存储在临时表中,按照与一般表相同的方式使用该临时表的功能。从概念上来看它与嵌套视图比较类似,但各自有其优缺点。优点在于子查询如果被多次引用,使用嵌套视图就需要被执行多次,尤其在海量数据中满足条件的结果非常少得情况下,两者差别很明显。
使用WITH子查询的优点就在于其复杂查询语句只需要执行一次,但结果可以在同一个查询语句中被多次使用。
缺点是使用WITH子查询,由于不允许执行查询语句变形,所以无效的情况也比较多。尤其是WITH中的查询语句所创建的临时表无法拥有索引,当其查询结果的数据量比较大的时候,很可能会影响执行效率。
下面通过一个是示例看看。
640?wx_fmt=png&wxfrom=5&wx_lazy=1
/*从上面可以看出,在WITH中有两个子查询语句,但只创建了一个临时表,这是因为WITH中的第二个子查询使用的是第一个子查询的执行结果。在这种情况下,逻辑上只允许创建一个临时表,没有必要再次创建。在处理WITH临时表时,如果临时表可以被优先执行而且可以缩减连接之前的数据量,就可以采用嵌套循环连接,否则必须使用哈希连接*/
6.子查询缓存
针对某些子查询操作,优化器可以将子查询的结果进行缓存,避免重复读取。这一特性在FILTER型的子查询或标量子查询中都能观察到。看一个示例。
640?wx_fmt=png&wxfrom=5&wx_lazy=1
/*注意Id=3步骤的Start=3(emp表中的deptno有3个不同的值,这里就重复执行3次)。这体现了Cache技术,标量子查询中也有类似的Cache技术。*/
子查询相关文章:
Oracle性能优化之查询转换类-自查询
分享到:
评论

相关推荐

    收获,不止SQL优化--抓住SQL的本质1

    - **全书总结**:本书不仅是一本关于SQL优化的技术书籍,更是引导读者进入SQL优化世界的指南。通过丰富的案例、实战经验和深入的技术探讨,帮助读者建立起从宏观到微观的优化思路,并最终达到“爽”的境界。 - **...

    Inside Microsoft SQL Server 2008 T-SQL Programming.pdf

    - **查询优化**:包括如何分析查询计划、识别性能瓶颈、使用索引改进查询性能等。 - **存储优化**:讲解了如何合理规划表结构、使用分区技术提高大型表的访问速度。 - **资源管理**:介绍了SQL Server 2008中的一些...

    sqlserver2005-SQL查询-SQL程序设计-存储设计-查询调整优化

    在SQL Server 2005中,SQL查询和程序设计是数据库管理的核心组成部分,而存储设计和查询调整优化则是确保高效数据库性能的关键。这四本书籍涵盖了SQL Server 2005的重要知识点,旨在帮助读者深入理解并掌握该平台的...

    Microsoft SQL Server 2008技术内幕:T-SQL查询.pdf

    《Microsoft SQL Server 2008技术...通过对这本书的学习,读者将能够熟练掌握SQL Server 2008中的T-SQL查询技巧,从而更高效地管理和操作数据库。无论是数据库管理员、开发人员还是数据分析人员,都能从中受益匪浅。

    SQL优化表单查询-达梦数据库.pptx

    本篇文章主要探讨的是针对达梦数据库的SQL优化,特别是单表查询的优化策略。 首先,了解SQL优化的基础概念至关重要。在达梦数据库中,SQL的执行过程可以看作一系列操作符的组合,例如NSET、PRJT2、CSCN2、SSEK、...

    sql-map-2.dtd和sql-map-config-2.dtd

    本文将深入探讨与“sql-map-2.dtd”和“sql-map-config-2.dtd”相关的知识点,以及它们在Ibatis中的作用。 Ibatis是一个轻量级的ORM(对象关系映射)框架,它允许开发者将SQL语句直接写在配置文件中,通过XML映射...

    Microsoft SQL Server 2008技术内幕:T-SQL查询

    主要内容包括SQL的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表表达式、排名函数、数据聚合和透视转换、TOP和APPLY、数据修改、分区表、特殊数据结构等实际应用时会遇到的各种高级查询问题和解决...

    SQL优化·脑图-私房整理版

    SQL优化相关知识点整理,希望对大家有所帮助!

    ORACLE-SQL性能优化大全.pdf

    - **改写SQL语句**:利用SQL提示(HINT)、优化查询逻辑等方式改进语句。 - **物理结构调整**:如分区表、表空间等。 - **SQL共享原理**: - **共享池**:Oracle在内存中有一个共享池,用于存储已经解析过的SQL...

    SQL optimizer and rewriter. - SQL 优化器、重写器(辅助 SQL 调优)

    - SQL 优化器、重写器(辅助 SQL 调优)。SQL optimizer and rewriter. - SQL 优化器、重写器(辅助 SQL 调优)。SQL optimizer and rewriter. - SQL 优化器、重写器(辅助 SQL 调优)。SQL optimizer and rewriter. - ...

    18 SQL优化--其他SQL的优化.doc

    根据提供的文档标题、描述、标签以及部分内容,我们可以深入探讨关于SQL优化的相关知识点,特别是针对MySQL中的表分析、检查、优化以及其他SQL语句的优化策略。 ### 表分析、检查与优化 #### 表分析(Analyze ...

    Microsoft SQL SERVER 2008技术内幕 T-SQL查询

    2. **子查询与联接查询**:深入讲解如何使用子查询进行复杂的数据筛选,以及如何通过联接查询处理多表数据,包括嵌套子查询、存在子查询、IN和NOT IN子查询等。 3. **聚合函数与分组统计**:介绍COUNT、SUM、AVG、...

    learn-sql-the-hard-way-笨方法学sql

    4. **子查询**(learn-sql-the-hard-waych12.html) - 内部子查询和外部子查询 - 使用IN、NOT IN、ANY、ALL操作符 - 作为FROM子句的子查询 - 使用子查询进行多表操作 5. **插入、更新与删除**(learn-sql-the-...

    基于案例学习SQL优化

    在“基于案例学习SQL优化”的课程中,我们主要探讨如何提升数据库性能,特别是针对SQL查询的优化技巧。DBA(数据库管理员)作为关键角色,需要掌握这些技能来确保系统的高效运行。以下是根据课程标题和描述提炼出的...

    SQL Server 数据库技术---基础篇、数据库安全、SQL开发、数据库性能优化

    SQL Server 数据库技术---基础篇(T-SQL基础、数据库几本操作、SQL Server 2008新特性)、数据库安全(SQL Server 2008 安全数据...、数据库性能优化(数据库存储与索引、数据查询、事务处理、数据库系统调优 工具)

    优化sql查询速度

    以下是从标题、描述及部分给定内容中提炼出的关键知识点,这些内容将帮助我们深入了解如何有效地优化 SQL 查询。 #### 1. 优化 SQL 查询的基本原则 - **明确查询目的**:在编写 SQL 语句之前,首先要明确查询的...

    Microsoft SQL Server 2005技术内幕:T-SQL查询

    《Microsoft SQL Server 2005技术内幕:T-SQL查询》是一本专注于SQL Server 2005数据库管理系统中T-SQL(Transact-SQL)查询语言的专著。这本书是技术内幕系列的一部分,旨在为读者提供深入、全面的T-SQL查询知识,...

    收获,不止SQL优化--抓住SQL的本质

    优化查询包括合理使用索引、避免全表扫描、减少子查询、正确使用JOIN操作以及避免使用NOT IN和OR等低效运算符。 2. **索引策略**:索引是提高查询速度的关键。书中会介绍何时创建索引、如何选择合适的索引类型(如B...

    ORACLE中SQL查询优化技术

    - **减少子查询使用**:将复杂的子查询转换为连接操作或者使用物化视图等技术来减少查询复杂度。 - **合理使用JOIN操作**:正确使用内连接(`INNER JOIN`)、外连接(`LEFT JOIN`, `RIGHT JOIN`)等连接方式,确保只获取...

Global site tag (gtag.js) - Google Analytics