OR EXISTS语句的优化方法

2023-11-17

OR EXISTS语句的优化方法:
这库一直很空闲,但无意中看了一下,发现其中很多语句都很有问题,都是典型的OR问题语句,如果并发量大的话,CPU一下子就飙高了。
OR语句一直是性能杀手,当存在一两个的时候一般可以用union和union all来优化,请看以下例子。
1.在原句中使用了or语句并且or语句里面使用exists语句,这样给优化器造成了很大的迷惑。
2.从执行计划看来,貌似没有什么问题。
3.但从统计数据来看,一致读非常高,达到了4百多万次。
select count(*)
  from UNIOMS0808.SETTLEMENT s
 where (settlementStatus = 3)
   and (companyCode like '%GDSPID01687%' or exists
        (select 1
           from UNIOMS0808.PROVIDER pro
          where s.companyCode = pro.cpId
            and pro.companyId in
                (select com.companyId
                   from UNIOMS0808.COMPANY com
                  where com.companyCode like '%GDSPID01687%')));
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=164 Card=1 Bytes=14)
   1    0   SORT (AGGREGATE)
   2    1     FILTER
   3    2       TABLE ACCESS (FULL) OF 'SETTLEMENT' (Cost=164 Card=1939 Bytes=27146)
   4    2       NESTED LOOPS (Cost=375 Card=190 Bytes=6840)
   5    4         TABLE ACCESS (FULL) OF 'PROVIDER' (Cost=20 Card=355 Bytes=4615)
   6    4         TABLE ACCESS (BY INDEX ROWID) OF 'COMPANY' (Cost=1 Card=1 Bytes=23)
   7    6           INDEX (UNIQUE SCAN) OF 'PK_COMPANY' (UNIQUE)
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
    4726442  consistent gets
          0  physical reads
          0  redo size
        406  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
优化思路:直接将or语句转换为union语句观察一下。
select count(1)
from 
(
select SETTLEMENTID
  from UNIOMS0808.SETTLEMENT s
 where (settlementStatus = 3)
   and (companyCode like '%GDSPID01687%')
union
select SETTLEMENTID
  from UNIOMS0808.SETTLEMENT s
 where (settlementStatus = 3)
   and exists(select 1
           from UNIOMS0808.PROVIDER pro, UNIOMS0808.COMPANY com
          where s.companyCode = pro.cpId
            and pro.companyId =com.companyId
            and com.companyCode like '%GDSPID01687%')
);
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=376 Card=1)
   1    0   SORT (AGGREGATE)
   2    1     VIEW (Cost=376 Card=1199)
   3    2       SORT (UNIQUE) (Cost=376 Card=1199 Bytes=37355)
   4    3         UNION-ALL
   5    4           TABLE ACCESS (FULL) OF 'SETTLEMENT' (Cost=164 Card=994 Bytes=24850)
   6    4           HASH JOIN (Cost=199 Card=205 Bytes=12505)
   7    6             NESTED LOOPS (Cost=34 Card=14 Bytes=504)
   8    7               TABLE ACCESS (FULL) OF 'PROVIDER' (Cost=20 Card=14 Bytes=182)
   9    7               TABLE ACCESS (BY INDEX ROWID) OF 'COMPANY' (Cost=1 Card=1 Bytes=23)
  10    9                 INDEX (UNIQUE SCAN) OF 'PK_COMPANY' (UNIQUE)
  11    6             TABLE ACCESS (FULL) OF 'SETTLEMENT' (Cost=164 Card=19884 Bytes=497100)
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       1917  consistent gets
          0  physical reads
          0  redo size
        406  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed
观察效果:效果非常明显,一致读下降到2千个,是原来的千分之0.4。从执行计划中看最大不同在于新的执行计划使用了hash join,而且显示的cost比原来的还要大。
问题分析:由于or exists语句导致优化器选择了nested loops进行表连接,而nested loops对于少数据量处理是很好的,但对于全表扫描来说则效率更低,最终导致大量的一致读产生。
有兴趣的可以进一步使用10046事件进行分析,确定问题的症结。
以下提供可重现的测试方法
create table test as select * from dba_objects;
create table test1 as select * from dba_objects;
优化前
select count(*)
  from test s
 where (OBJECT_TYPE = 'VIEW')
   and (OBJECT_NAME like '%DBA_TABLES%' or exists
        (select 1
           from test1 pro
          where s.object_id = pro.object_id
            and pro.OBJECT_NAME = 'DBA_TABLES'));
            
优化后
select count(1)
from 
(
select object_id
  from test s
 where (OBJECT_TYPE = 'VIEW')
   and (OBJECT_NAME like '%DBA_TABLES%')
UNION   
select object_id
  from test s
 where (OBJECT_TYPE = 'VIEW')
   and exists
        (select 1
           from test1 pro
          where s.object_id = pro.object_id
            and pro.OBJECT_NAME = 'DBA_TABLES')
);            

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/13605188/viewspace-706829/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/13605188/viewspace-706829/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OR EXISTS语句的优化方法 的相关文章

  • 为什么使用abs()或fabs()而不是条件否定?

    在 C C 中 为什么要使用abs or fabs 不使用以下代码即可查找变量的绝对值 int absoluteValue value lt 0 value value 这与较低级别的指令较少有关吗 您提出的 有条件的abs 并不等于std
  • 为什么基类必须有一个带有 0 个参数的构造函数?

    这不会编译 namespace Constructor0Args class Base public Base int x class Derived Base class Program static void Main string a
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • ASP .NET MVC,创建类似路由配置的永久链接

    我需要帮助在 MVC 网站中创建类似 URL 路由的永久链接 Slug 已设置为 www xyz com profile slug 代码为 routes MapRoute name Profile url profile slug defa
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • VS30063:您无权访问 https://dev.azure.com

    我正在尝试在 asp net core 2 1 mvc 应用程序中使用以下代码连接 Azure DevOps Uri orgUrl new Uri https dev azure com xxxxx String personalAcces
  • 禁用 LINQ 上下文的所有延迟加载或强制预先加载

    我有一个文档生成器 目前包含约 200 个项目的查询 但完成后可能会超过 500 个 我最近注意到一些映射表示延迟加载 这给文档生成器带来了一个问题 因为它需要根据生成的文档来访问所有这些属性 虽然我知道DataLoadOptions可以指
  • 两组点之间的最佳匹配

    I ve got two lists of points let s call them L1 P1 x1 y1 Pn xn yn and L2 P 1 x 1 y 1 P n x n y n 我的任务是找到它们点之间的最佳匹配 以最小化它
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • std::bind 重载解析

    下面的代码工作正常 include
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • 通过等待任务或访问其 Exception 属性都没有观察到任务的异常

    这些是我的任务 我应该如何修改它们以防止出现此错误 我检查了其他类似的线程 但我正在使用等待并继续 那么这个错误是怎么发生的呢 通过等待任务或访问其 Exception 属性都没有观察到任务的异常 结果 未观察到的异常被终结器线程重新抛出
  • C# 搜索目录中包含字符串的所有文件,然后返回该字符串

    使用用户在文本框中输入的内容 我想搜索目录中的哪个文件包含该文本 然后我想解析出信息 但我似乎找不到该字符串或至少返回信息 任何帮助将不胜感激 我当前的代码 private void btnSearchSerial Click object
  • 过期时自动重新填充缓存

    我当前缓存方法调用的结果 缓存代码遵循标准模式 如果存在 则使用缓存中的项目 否则计算结果 在返回之前将其缓存以供将来调用 我想保护客户端代码免受缓存未命中的影响 例如 当项目过期时 我正在考虑生成一个线程来等待缓存对象的生命周期 然后运行
  • Silverlight Datagrid:在对列进行排序时突出显示整个列

    我的 Silverlight 应用程序中有一个 DataGrid 我想在对该列进行排序时突出显示整个列 它在概念上与上一个问题类似 Silverlight DataGrid 突出显示整列 https stackoverflow com qu
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 运行代码首先迁移更新数据库时出错

    我在迁移到数据库时遇到问题 并且似乎找不到我遇到的错误的答案 System MissingMethodException Method not found System Data Entity Migrations Builders Tab
  • 过度使用委托对性能来说是一个坏主意吗? [复制]

    这个问题在这里已经有答案了 考虑以下代码 if IsDebuggingEnabled instance Log GetDetailedDebugInfo GetDetailedDebugInfo 可能是一个昂贵的方法 因此我们只想在调试模式

随机推荐

  • 智能聊天机器人实现(源码+解析)

    前言 之前写了一篇 美女图片采集器 源码 解析 得到了众多朋友的支持 发现这样系列的教程还是挺受欢迎的 也激励我继续写下去 也在那一篇文章中提过 美女图片采集只是我先前那个完整APP中的一个功能罢了 还有其他几个比较好玩的尚未开源 之后有时
  • QWidgetAction实现鼠标滑过菜单项图标高亮显示

    需求是鼠标滑过菜单项时 菜单项的文字 icon以及子菜单的小箭头都要高亮显示 qss中只能设置item背景色 文字颜色以及子菜单小箭头的样式 icon的图片不能切换 另外曾经想过用indicator 对action setCheckable
  • Ubuntu18.04安装QT5

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 QT5是什么 二 安装包安装 1 下载安装包 2 安装QT5 3 运行 4 其他方式 总结 前言 最近在学习QT5 在Windows上的安装自然不必多说
  • 爬虫 — 反爬

    目录 一 UA 反爬 二 Cookie 验证与反爬 1 Cookie 简介 2 使用 Cookie 原因 3 Cookie 作用 3 1 模拟登录 3 2 反反爬 三 Referer 反爬 一 UA 反爬 UA User Agent 用户代
  • [机械]“重工业面临两大危机”——向文波(三一重工股份有限公司执行总裁)

    向文波 三一重工股份有限公司执行总裁 向文波是三一重工的掌门人 但深受徐工事件影响 他以业内的视角 适时地向中国重工业的改革发出一个警示信号 提出一个超越 抓大放小 国进民退 等传统国企改革的新命题 产业安全 引起了舆论与政府的重视 中国重
  • 2021.11.13-15总结

    将C语言文件相关的内容学完了 了解了文件相关的函数
  • linux网络管理

    一 网络接口 1 在Linux系统中 主机的网络接口卡通常称为网络接口 使用ifconfig命令来查看网络 2 eth0 是Linux系统中第一块以太网卡的名称 3 lo 是Linux系统中的 环回 网络接口 lo 并不代表真正的网络接口
  • 用户访问session分析-按session粒度进行数据聚合

    思路 之前模拟创建了两张表 user visit action 和 user info 对于user visit action表 1 通过用户传过来的指定日期范围内 从user visit action中查询出指定的用户访问数据 变成 ac
  • nginx根据url参数动态代理

    nginx根据url参数动态代理 请求url格式 其中参数proxy后面的url就是需要访问的真实地址 http localhost 9388 proxy http localhost 8038 Content layui font ico
  • 腾讯滑块识别-通用滑块识别

    遇到滑块问题 在写爬虫的时候 经常会遇到滑块问题 很多次都想过尝试如何攻破滑块 但是每次都没成功 除了最开始的极验滑块 当时通过原图和滑块图的对比 能够得出缺口坐标 但是随着极验 网易 腾讯滑块的更新 已经不能够找到原图了 下面给出滑块通杀
  • python的gui神器——gooey

    python的gui神器 gooey python自带的gui库 tkinter库 最近研究的gui库 gooey tkinter教程 tkinter GUI编程 gooey地址和教程 gooey 入门教程 python使用tkinter库
  • Android基础知识 - 内置SQLite数据库

    文章目录 SQLite数据库简单介绍 创建数据库 SQLiteOpenHelper类 简单概述 DatabaseTest项目 升级数据库 对表中的数据进行操作 添加数据 更新数据 删除数据 查询数据 使用SQL操作数据库 SQLite数据库
  • 03 xxl-job任务执行流程

    作业类型 xxl job支持七种作业类型 Bean GLUE Java GLUE Shell GLUE Python GLUE PHP GLUE Nodejs GLUE PowerShell 其中 GLUE类型作业都是在admin管理端编辑
  • Unity3d Survival Shooter Tutorial 学习笔记(八)---游戏结束

    1 在HUDCanvas下新建Image ScreenFader 设置为全屏显示 且颜色设置为浅蓝 2 添加GameOverText 并设置Text参数 3 调整HUDCanvas顺序 与就是渲染顺序 4 初始化时 把GameOverTex
  • 用Eigen库练习代数运算方式以便后续对刚体旋转和移动做基础

    include
  • qt背景渐变色的效果

    background color qlineargradient spread pad x1 0 y1 0 x2 0 y2 1 stop 0 87CEFA stop 1 292F38 背景颜色 画线部分可以达到渐变的效果图
  • CentOS 下安装 Docker

    要求 要安装 Docker 我们需要 CentOS 7 及以上的发行版本 建议使用overlay2存储驱动程序 卸载已有 Docker 如果你已经安装过旧版的 Docker 可以先执行以下命令卸载旧版 Docker sudo yum rem
  • sqli-labs解题大法29 ~40

    Less 29 堆叠查询 在一条语句之后加上分号 然后接下一条语句 可以一次执行多条语句 order by 排序 可以 联合查询 可以 参考Less 1 Background 6 服务器 两层 架构 http www cnblogs com
  • Linux笔记

    Linux 基础笔记 Linux文件目录 目录 描述 Linux系统根目录 bin usr bin 可执行二进制文件的目录 如常用的命令ls tar mv cat等 boot 存放Linux系统启动时用到的一些文件 如Linux内核文件 b
  • OR EXISTS语句的优化方法

    OR EXISTS语句的优化方法 这库一直很空闲 但无意中看了一下 发现其中很多语句都很有问题 都是典型的OR问题语句 如果并发量大的话 CPU一下子就飙高了 OR语句一直是性能杀手 当存在一两个的时候一般可以用union和union al