iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >如何理解SQL优化中连接谓词推入
  • 735
分享到

如何理解SQL优化中连接谓词推入

2024-04-02 19:04:59 735人浏览 独家记忆
摘要

这篇文章将为大家详细讲解有关如何理解sql优化中连接谓词推入,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 SQL优化之连接谓词

这篇文章将为大家详细讲解有关如何理解sql优化中连接谓词推入,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

SQL优化之连接谓词推入:

环境准备:
create table emp1 as select * from emp;
create table emp2 as select * from emp;
create index idx_emp1 on emp1(empno);
create index idx_emp2 on emp2(empno);
create or replace  view  emp_view as select emp1.empno as empno1 from emp1;
create or replace view emp_view_uNIOn as select emp1.empno as empno1 from emp1 union all select emp2.empno as empno1 from emp2;


赋权,scott用户可以开启set autot
grant select on v_$sesstat to scott;
grant select on v_$statname to scott;
grant select on v_$mystat to scott;


sql范例1:
select emp.empno from emp,emp_view where emp.empno=emp_view.empno1(+) and emp.ename='FROD';
可以看到emp表和emp_view视图左外连接,视图是补充表。


查看执行计划:
SQL> set autot traceonly
SQL> set line 250
SQL> select emp.empno from emp,emp_view where emp.empno=emp_view.empno1(+) and emp.ename='FROD';


no rows selected




Execution Plan
----------------------------------------------------------
Plan hash value: 101695337


------------------------------------------------------------------------------------
| Id  | Operation               | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |          |     1 |    12 |     4   (0)| 00:00:01 |
|   1 |  NESTED LOOPS OUTER     |          |     1 |    12 |     4   (0)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL     | EMP      |     1 |    10 |     3   (0)| 00:00:01 |
|   3 |   VIEW PUSHED PREDICATE | EMP_VIEW |     1 |     2 |     1   (0)| 00:00:01 |
|*  4 |    INDEX RANGE SCAN     | IDX_EMP1 |     1 |    13 |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------


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


   2 - filter("EMP"."ENAME"='FROD')
   4 - access("EMP1"."EMPNO"="EMP"."EMPNO")


Note
-----
   - dynamic sampling used for this statement (level=2)




Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          7  consistent gets
          0  physical reads
          0  redo size
        333  bytes sent via SQL*Net to client
        508  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed


该执行计划比较好理解:步骤2与步骤3同级,但是步骤2没有子ID,所以最先执行步骤2.
步骤2:该步骤有一个filter条件filter("EMP"."ENAME"='FROD'),全表扫描emp表,找出ename=frod的所有数据
步骤4:索引范围扫描,目标条件满足access("EMP1"."EMPNO"="EMP"."EMPNO"),这里把视图和表左外连接的条件推入到了视图中。
步骤3:VIEW PUSHED PREDICATE说明没有做视图合并,把视图当做一个独立单元来执行,但是把外部条件推入到了视图内部
。如果没有做这次连接谓词推入,那么就不会在抓取视图内部数据的时候用到emp1表上的索引,那样的话就会全表扫描了。
步骤1:然后两个结果集做循环嵌套外连接,得到结果。


下面验证一下,连接谓词未推入,抓取视图数据集的时候不会走emp1的索引,而是全表扫描emp1了。
select emp.empno from emp,emp_view where emp.empno=emp_view.empno1(+) and emp.ename='FROD';


Execution Plan
----------------------------------------------------------
Plan hash value: 3053348535


-----------------------------------------------------------------------------------------
| Id  | Operation                    | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |          |     1 |    23 |     6  (17)| 00:00:01 |
|   1 |  MERGE JOIN OUTER            |          |     1 |    23 |     6  (17)| 00:00:01 |
|*  2 |   TABLE ACCESS BY INDEX ROWID| EMP      |     1 |    10 |     2   (0)| 00:00:01 |
|   3 |    INDEX FULL SCAN           | PK_EMP   |    14 |       |     1   (0)| 00:00:01 |
|*  4 |   SORT JOIN                  |          |    14 |   182 |     4  (25)| 00:00:01 |
|   5 |    VIEW                      | EMP_VIEW |    14 |   182 |     3   (0)| 00:00:01 |
|   6 |     TABLE ACCESS FULL        | EMP1     |    14 |   182 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------


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


   2 - filter("EMP"."ENAME"='FROD')
   4 - access("EMP"."EMPNO"="EMP_VIEW"."EMPNO1"(+))
       filter("EMP"."EMPNO"="EMP_VIEW"."EMPNO1"(+))


Note
-----
   - dynamic sampling used for this statement (level=2)




Statistics
----------------------------------------------------------
         11  recursive calls
          0  db block gets
          9  consistent gets
          1  physical reads
          0  redo size
        333  bytes sent via SQL*Net to client
        508  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed


这时可以看到对emp表进行索引全扫描,利用条件"EMP"."ENAME"='FROD'回表,得到数据集;视图并没有走emp1的索引,而是全表扫描,并将结果进行排序,然后与第一个结果集进行排序合并外连接。


范例sql:
select emp.empno from emp,emp_view_union where emp.empno=emp_view_union.empno1 and emp.ename='FROD';
Execution Plan
----------------------------------------------------------
Plan hash value: 2223410919


-------------------------------------------------------------------------------------
| Id  | Operation                     | Name           | Rows  | Bytes | Cost (%CPU)|
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |                |     2 |    24 |     5   (0)|
|   1 |  NESTED LOOPS                 |                |     2 |    24 |     5   (0)|
|*  2 |   TABLE ACCESS FULL           | EMP            |     1 |    10 |     3   (0)|
|   3 |   VIEW                        | EMP_VIEW_UNION |     1 |     2 |     2   (0)|
|   4 |    UNION ALL PUSHED PREDICATE |                |       |       |            |
|*  5 |     INDEX RANGE SCAN          | IDX_EMP1       |     1 |    13 |     1   (0)|
|*  6 |     INDEX RANGE SCAN          | IDX_EMP2       |     1 |    13 |     1   (0)|
-------------------------------------------------------------------------------------


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


   2 - filter("EMP"."ENAME"='FROD')
   5 - access("EMP1"."EMPNO"="EMP"."EMPNO")
   6 - access("EMP2"."EMPNO"="EMP"."EMPNO")


Note
-----
   - dynamic sampling used for this statement (level=2)




Statistics
----------------------------------------------------------
         28  recursive calls
          0  db block gets
         39  consistent gets
          0  physical reads
          0  redo size
        333  bytes sent via SQL*Net to client
        508  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed
因为视图定义中有union all,所以EMP_VIEW_UNION不能做视图合并,但是可以做连接谓词推入,所以看到步骤5和步骤6将连接条件推入到了视图内部,从而走了emp1和emp2表的索引。然后将结果集与全表扫描emp表得到的ename=frod的结果集做循环嵌套连接,得到最终结果。
同样地,如果阻止了连接谓词推入,那么视图内部结果集会按照全表扫描。


select emp.empno from emp,emp_view_union where emp.empno=emp_view_union.empno1 and emp.ename='FROD';


Execution Plan
----------------------------------------------------------
Plan hash value: 894575737
------------------------------------------------------------------------------------
| Id  | Operation                    | Name           | Rows  | Bytes | Cost (%CPU)|
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                |     2 |    46 |     9  (12)|
|   1 |  MERGE JOIN                  |                |     2 |    46 |     9  (12)|
|*  2 |   TABLE ACCESS BY INDEX ROWID| EMP            |     1 |    10 |     2   (0)|
|   3 |    INDEX FULL SCAN           | PK_EMP         |    14 |       |     1   (0)|
|*  4 |   SORT JOIN                  |                |    28 |   364 |     7  (15)|
|   5 |    VIEW                      | EMP_VIEW_UNION |    28 |   364 |     6   (0)|
|   6 |     UNION-ALL                |                |       |       |            |
|   7 |      TABLE ACCESS FULL       | EMP1           |    14 |   182 |     3   (0)|
|   8 |      TABLE ACCESS FULL       | EMP2           |    14 |   182 |     3   (0)|
------------------------------------------------------------------------------------


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


   2 - filter("EMP"."ENAME"='FROD')
   4 - access("EMP"."EMPNO"="EMP_VIEW_UNION"."EMPNO1")
       filter("EMP"."EMPNO"="EMP_VIEW_UNION"."EMPNO1")


Note
-----
   - dynamic sampling used for this statement (level=2)




Statistics
----------------------------------------------------------
         14  recursive calls
          0  db block gets
         14  consistent gets
          0  physical reads
          0  redo size
        333  bytes sent via SQL*Net to client
        508  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed
注意:能否做谓词推入,与视图能否合并,是否是内嵌视图没有关系,与目标视图的类型,与外部查询之间的连接类型以及连接方法有关。
如下是一个无法谓词推入的sql:
原因:视图在外链接的右侧。
select emp.empno from emp,emp_view where emp.empno=emp_view.empno1 and ename='FROD';


Execution Plan
----------------------------------------------------------
Plan hash value: 3774177413


--------------------------------------------------------------------------------
| Id  | Operation           | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |          |     1 |    23 |     6   (0)| 00:00:01 |
|   1 |  NESTED LOOPS       |          |     1 |    23 |     6   (0)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL | EMP      |     1 |    10 |     3   (0)| 00:00:01 |
|*  3 |   VIEW              | EMP_VIEW |     1 |    13 |     3   (0)| 00:00:01 |
|   4 |    TABLE ACCESS FULL| EMP1     |    14 |   182 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------


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


   2 - filter("ENAME"='FROD')
   3 - filter("EMP"."EMPNO"="EMP_VIEW"."EMPNO1")


Note
-----
   - dynamic sampling used for this statement (level=2)




Statistics
----------------------------------------------------------
         11  recursive calls
          0  db block gets
         14  consistent gets
          0  physical reads
          0  redo size
        333  bytes sent via SQL*Net to client
        508  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed


连接谓词推入条件:
视图定义语句中存在union all/union/group by/distinct
视图与外部查询之间是外连接,半连接,反连接
以上只要满足一种条件就可以谓词推入,比如内连接,但是视图定义语句中有union all。
如上面的范例sql:select emp.empno from emp,emp_view_union where emp.empno=emp_view_union.empno1 and emp.ename='FROD';

关于如何理解SQL优化中连接谓词推入就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

您可能感兴趣的文档:

--结束END--

本文标题: 如何理解SQL优化中连接谓词推入

本文链接: https://www.lsjlt.com/news/68055.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何理解SQL优化中连接谓词推入
    这篇文章将为大家详细讲解有关如何理解SQL优化中连接谓词推入,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 SQL优化之连接谓词...
    99+
    2024-04-02
  • 如何理解MySQL性能优化:长连接、短连接、连接池
    本篇内容介绍了“如何理解MySQL性能优化:长连接、短连接、连接池”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有...
    99+
    2024-04-02
  • 如何理解SQL Server SQL性能优化中的参数化
    如何理解SQL Server SQL性能优化中的参数化,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。数据库参数化的模式数据库的...
    99+
    2024-04-02
  • 如何优化MySQL连接数管理
    如何优化MySQL连接数管理 MySQL 是一种流行的关系型数据库管理系统,广泛应用于各种网站和应用程序中。在实际的应用过程中,MySQL 连接数管理是一个非常重要的问题,尤其是在高并...
    99+
    2024-04-02
  • SQL拼接中的性能如何优化
    SQL拼接会影响查询性能,特别是在处理大量数据时。以下是一些优化SQL拼接性能的方法: 使用参数化查询:参数化查询可以避免SQL...
    99+
    2024-04-29
    SQL
  • 如何理解SQL子查询优化
    这篇文章主要介绍“如何理解SQL子查询优化”,在日常操作中,相信很多人在如何理解SQL子查询优化问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解SQL子查询优化”的疑惑...
    99+
    2024-04-02
  • 如何理解Python接口优化
    这篇文章主要讲解了“如何理解Python接口优化”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何理解Python接口优化”吧!背景我们负责的一个业务平台,有次在发现设置页面的加载特别特别地...
    99+
    2023-06-15
  • 如何解析MySQL性能优化中的SQL优化
    如何解析MySQL性能优化中的SQL优化,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。注:以 MySQL 为背景,很多内容同时适用于其他关系型...
    99+
    2024-04-02
  • Go语言中如何处理并发数据库连接的连接池优化问题?
    Go语言中如何处理并发数据库连接的连接池优化问题?一、背景随着互联网应用的发展,数据库连接池的优化成为了开发者需要面临的重要问题。在Go语言中,通过使用连接池可以有效地管理和复用数据库连接,提升应用程序在并发访问数据库时的性能。本文将介绍在...
    99+
    2023-10-22
    优化 连接池 并发处理
  • Go语言中如何处理并发数据库连接的连接池优化问题
    在Go语言中,可以使用`database/sql`包来处理数据库连接的连接池优化问题。`database/sql`包提供了`sql....
    99+
    2023-10-09
    Go语言
  • 如何理解MySQL中per_thread_buffers优化
    如何理解MySQL中per_thread_buffers优化,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。 &...
    99+
    2024-04-02
  • win7优化后找不到本地连接如何解决
    这篇文章主要讲解了“win7优化后找不到本地连接如何解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“win7优化后找不到本地连接如何解决”吧!win7优化后找不到本地连接解决方法首先右键计...
    99+
    2023-07-01
  • PHP开发中如何调试和优化数据库连接
    引言:在PHP开发中,数据库是一个非常关键的组成部分,良好的数据库连接调试和优化可以有效提高网站的性能。本文将介绍如何调试和优化数据库连接,并提供了一些具体的代码示例。一、调试数据库连接:使用PDO方式连接数据库:通过PDO连接数据库,可以...
    99+
    2023-10-21
    调试:PHP数据库调试 优化:PHP数据库优化 连接:PHP数据库连接
  • 如何深入理解Java中的接口
    今天就跟大家聊聊有关如何深入理解Java中的接口,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、前言前面我们说了抽象类的概述,我们对抽象类也有个认识和理解了,现在我们学习十分重要的...
    99+
    2023-06-21
  • 如何深入理解Sql Server中的表扫描
    如何深入理解Sql Server中的表扫描,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。  很久...
    99+
    2024-04-02
  • Java Hibernate中的连接池该如何理解
    本篇文章为大家展示了Java Hibernate中的连接池该如何理解,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Hibernate支持第三方的连接池,官方推荐的连接池是C3P0,Proxool,以...
    99+
    2023-06-17
  • 自然语言处理中的算法优化:如何实现词向量模型?
    自然语言处理(Natural Language Processing, NLP)是人工智能领域的一个重要分支。在NLP中,词向量模型是实现文本分类、聚类、情感分析等任务的基础。而优化词向量模型的算法,是提高NLP算法效果的关键之一。本文将介...
    99+
    2023-08-27
    编程算法 自然语言处理 linux
  • PHP开发中如何优化数据库连接和查询性能
    在现代的Web开发中,数据库连接和查询性能是一个非常重要的问题。随着用户数量的增加和业务需求的复杂化,一个高性能的数据库连接和查询系统能够显著提升网站的响应速度和用户体验。本文将介绍一些在PHP开发中优化数据库连接和查询性能的方法,并提供具...
    99+
    2023-10-21
    查询性能优化 数据库连接优化
  • NumPy如何优化ASP接口容器中的数据处理?
    在今天的数据处理领域中,NumPy已经成为了不可或缺的工具。NumPy是Python语言中用于科学计算的一个库,它提供了高级的数据结构以及简单易用的接口,让用户可以轻松地进行数据处理和分析。在ASP接口容器中,NumPy更是有着不可替代的...
    99+
    2023-09-15
    接口 容器 numpy
  • 如何优化数据库连接池管理,提高应用程序的效率
    一、数据库连接池概述 数据库连接池是一组预先建立的数据库连接,应用程序可以从连接池中获取连接来访问数据库。使用连接池可以避免频繁创建和销毁数据库连接,从而提高应用程序的性能和可靠性。 二、数据库连接池管理的优化策略 1.合理设置连接池大...
    99+
    2024-02-25
    数据库连接池 连接池管理 JDBC HikariCP 性能优化
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作