Oracle SQL查询在查询中略有改动会导致大的结果返回时间差异。这是因为Oracle SQL查询是建立在关系数据库管理系统之上的,而关系数据库管理系统是通过表格形式来存储数据的。因此,当查询涉及到多个表格或者需要对表格进行连接时,如果这些表格之间存在大量的数据关联,那么查询的性能就会受到影响。
此外,Oracle SQL查询也存在着一些限制,比如不支持跨表格的连接查询等。因此,在进行查询时,需要根据具体情况进行优化,以确保查询的效率和准确性。
而对于大于3这种情况,虽然根据CHECK 的 约束和列定义,可以推断出这条 查询 不会 返回 任何记录,但是 Oracle 的 优化器并没有聪明到根据列 的 精度来进行分析,因此这个 查询 会 执行全表扫描。...可以看到,无论是执行 时间 ,还是逻辑读,两个 SQL 没有任何 的 差别。为了更好 的 证明 Oracle 并没有读取ID等于3 的 记录,执行下面的 查询 : ?...先构造一张 大 表,现在分别执行两个 查询 ,检查执行 结果 : 由于采用 的 都是全表扫描,二者执行 的 时间 和逻辑读完全一样。 下面建立一个物化视图: 下面检查系统设置是否满足 查询 重写: ?...1、 在 Check约束下,前者 会 执行全表扫描,后者经过check约束 的 检查后,通过filter结束 查询 ,能够更高效地 返回 结果 ; 2、 在 使用索引 的 时候,由于 Oracle 索引结构 的 特点,两者扫描 的 节点都是从4...开始, 在 执行计划和逻辑读,执行 时间 等各方面都不存在性能 差异 ; 3、 在 使用物化视图 的 过程 中 ,前者同时扫描物化视图和原表,效率较低。
例如,计算简单 的 数学表达式、获取系统 时间 、显示字符串等。这些 查询 不需要访问实际 的 业务数据,而DUAL表则提供了一个简便 的 占位符机制。 不同数据库 中 的 DUAL表 各大数据库对DUAL表 的 实现 略有 不同。...FROM DUAL; 这个 查询 会 返回 一行数据,即:Hello, World!。...DUAL表 在 Oracle 中 的 典型用途是执行没有实际表 的 计算,例如: SELECT SYSDATE FROM DUAL; 这条 SQL 会 返回 当前 的 系统日期和 时间 。... Oracle 中 的 DUAL表只有一行,因此无论你执行多少次 查询 , 结果 总是一行一列,且非常高效。 2....定期发送此 查询 来确保连接池中 的 连接仍然有效,可以避免数据库连接突然失效 导致 的 服务中断。 DUAL表作为一个伪表,虽然 在 不同数据库 中 的 实现和依赖程度有所不同,但其核心用途是一致 的 :用于无表 查询 。
2. 在 不能修改应用 中 的 SQL 的 情况下使 SQL 语句按指定 的 执行计划运行。...实际t1表符合t1.name like ‘%ABC%’条件 的 记录只有3条,优化器预估则是500条,即500/10000*100%=5%,应该是 Oracle 的 默认选择率,但关于这点, 略有 疑问,按照MOS(...因为实际t1使用like 的 结果 集很小,一个 大 表和一个小 的 结果 集关联,而且 大 表关联字段有索引,比较适合于Nested Loop连接。我们看下使用这种连接 的 执行计划, ?...Join 的 221,再看t1表 的 返回 行数预估是500,远高于实际like过滤后其实际 的 结果 集3,因此会对nested loop连接产生了一个过高 的 成本预估, 导致 优化器选择了Hash Join 的 执行计划,...这条 SQL 使用nested loop执行计划 中 T1表原始其预估行数是500,计算500*0.006=3,这就是为什么10053 的 trace以及执行计划中表t1 的 预估行数是3 的 原因,我们没有对 SQL 做任何一些 改动
在 某搜索网站 中 ,“ oracle 执行计划”关键字 的 搜索 结果 与“ oracle ”关键字 的 搜索 结果 占比为1.7%。足可见执行计划在 ORACLE 中举足轻重 的 地位: ?...我们对上述 SQL 稍加 改动 ,再看执行计划: 什么情况?DEPT表不见了,执行计划居然“残缺”了: 1、这是 ORACLE 的 BUG吗? 2、少了一张表, 结果 正确吗?...,即子 查询 D对整个 SQL 返回 的 结果 是没有任何影响 的 ,该 SQL 完全等价于如下 SQL : SELECT COUNT(1) FROM EMP E 而事实上呢,我们看看 ORACLE 的 执行计划: ?...其实,除了上述两种场景外,还有一种场景也 会 导致 table access full。我们先来看一个非常简单 的 案例,我们 在 EMP.DEPTNO上创建一个索引,因为经常会遇到 查询 某个特定部门 的 员工信息。...刚才 的 案例属于第一种,那么第二种又是怎么回事呢? 以下是一个真实 的 案例: 系统 中 存在一个日志表,数据量非常 大 ,我们对日志表按照日志 时间 (log_date)做了分区。
这个系统, 我能提出一些优化建议, 但是因为设计上 的 原因, 需要做很多大 的 改动 , 短期想看到效果是不可能 的 . 涉及到需要开发商 的 配合和较大 的 改动 , 这个 时间 就没法控制了.... oracle 为收集统计信息做了自动任务, 这个自动任务建议是要开启 的 , 否则就有可能不定时 的 出现 SQL 执行计划变差 导致 的 性能问题....有些资深dba用自己 的 脚本收集, 不太建议; dba可以结合业务特点, 在 默认收集任务 的 基础上做微调, 比如调整 时间 窗口, 与业务错开; 分区表增量收集; 大 表并行收集; 并发收集; 调整默认stale比例...写法与业务逻辑 的 实现方法: 大 结果 集 的 分页 查询 ,还有用分页 查询 的 逻辑做数据导出 , 都是不建议 的 ....分页就尽量把 结果 集缩小; 导出就一次性导出; 大 结果 集使用标量子 查询 ,执行 时间 会 很长, 而且并行也帮不上忙.
编辑手记: 在 SQL 执行 的 过程 中 ,选择不同 的 执行计划所产生 的 性能 差异 非常 大 ,因此能够符合业务地选择正确 的 执行计划非常重要。... 结果 排查发现客户 在 导入数据后并未重新收集统计信息, SQL 使用绑定变量,窥探 的 变量刚好是越界, 导致 SQL 第一次硬解析生成 的 执行计划走错。再加上10G 的 库 导致 接下来 的 执行计划直接沿用内存 中 的 执行计划。...value, 查询 id2>199走 的 索引范围扫( 结果 =0): ?...此时表 中 id2>199 的 数据已经有了大部分,但是由于统计信息未更新,谓词越界,再次 查询 大于199 的 SQL 依旧走 的 索引范围扫: 现在模拟变量窥探 的 问题,首先 查询 id2 大 于100 的 数据: ?...这里将内存 中 的 执行计划置为失效,这里方法有很多种,暂不做一一介绍: 从上面可以看出rows和bytes值都有 差异 ,如果数据 差异 大 ,cost也 会 变化。
端将从 查询 缓存 中 检索 结果 返回 给客户端,而不是再次解析执行 SQL , 查询 缓存在session之间共享,因此,一个客户端生成 的 缓存 结果 集,可以响应另一个客户端执行同样 的 SQL 。...query_cache_min_res_unit说明 默认大小是4KB,如果有很多 查询 结果 很小,那么默认数据块大小可能 会 导致 内存碎片,由于内存不足,碎片可能 会 强制 查询 缓存从缓存 中 删除 查询 。...开启queryCache场景 开启 查询 缓存时, 查询 语句第一次被执行时会将 SQL 文本及 查询 结果 缓存在QC 中 ,下一次执行同样 的 SQL 执行从QC 中 获取数据 返回 给客户端即可。...文本及数据,执行 时间 0.89s,由于开启了QC, SQL 文本及执行 结果 被缓存在QC 中 ,第二次执行执行同样 的 SQL 查询 语句,直接命中QC且 返回 数据,不需要发生硬解析,所以执行 时间 降低为0s,从profile...,然后锁定QC然后更新缓存 结果 , 会 导致 之前 的 缓存 结果 失效,再次执行相 的 查询 SQL 还是未命中,有得重新添加到QC,这样频繁 的 锁定QC->检查QC->添加QC->更新QC非常消耗资源,降低数据库 的 并发处理能力
编辑手记: Oracle 线上嘉年华,正在持续分享 中 。本次 的 主题是系统割接 中 的 SQL 解析问题和结合业务 的 SQL 优化改写技巧。...案例 中 的 SQL 如上,大致由两部分组成,上下各是一个标量子 查询 ,然后用union all联合在一起做了一个order by, 在 结果 显示中使用了分页。... 在 优化 SQL 中 ,我们优先考虑能否优化cost高 的 步骤,比如 大 表全表扫描、 大 表全索引快速扫描、跳跃索引扫描、 大 表排序等cost消耗; 其次看filter(优化了 的 nestedloop)、nested loop...注: 在 Oracle 的 估算 中 是不存在0 Rows 的 情况,如果评估 的 结果 是0, 会 算作1....(这里并不会改变 SQL 的 业务逻辑,虽然我们是先排序取rownum限制了,但是标量子 查询 时主 查询 是先排序还是后排序取rownum限制对于主 查询 返回 结果 集没有任何影响) 根据这种思路,我把 SQL 改写如下:
但是 InnoDB 实在太优秀了,最终 在 2006 年 的 时侯,成功吸引到 大 魔王 Oracle 的 注意,大手一挥,就把 InnoDB 收购了。...数据库 的 大小决定了故障恢复 的 时间 长短,InnoDB 可以利用事务日志进行数据恢复,这会比较快。主键 查询 在 InnoDB 引擎下也 会 相当快,不过需要注意 的 是如果主键太长也 会 导致 性能问题。...2.2.3 SQL 接口 SQL 接口用来接受客户端发送来 的 各种 SQL 命令,并且 返回 用户需要 的 查询 结果 。 等都在这里被处理。...语法检查通过后,解析器 会 查询 缓存,如果缓存中有对应 的 语句,就直接 返回 结果 不进行接下来 的 优化执行操作。...2.2.6 缓存 包括全局和引擎特定 的 缓存,提高 查询 的 效率。如果 查询 缓存中有命中 的 查询 结果 ,则 查询 语句就可以从缓存 中 取数据,无须再通过解析和执行。
♣ 在 Oracle 中 , SQL 优化 在 写法上有哪些常用 的 方法? 一般 在 书写 SQL 时需要注意哪些问题,如何书写可以提高 查询 的 效率呢?...实际上, Oracle 在 解析 的 过程 中 ,会将“*”依次转换成所有的列名,这个工作是通过 查询 数据字典完成 的 ,这意味着将耗费更多 的 时间 。...,如果子 查询 中 的 DEPTNO有NULL存在,那么整个 查询 都不会有 结果 , 在 Oracle 11g之前,如果主表和子表 的 DEPTNO未同时有NOT NULL约束,或都未加IS NOT NULL限制,那么 Oracle ...,尤其是要避免 在 同一个 SQL 中 多次访问同一张 大 表。...(41)对于一些固定性 的 小 的 查询 结果 集或统计性 的 SQL 语句(例如, SQL 语句非常复杂,但是最终 返回 的 结果 集很简单,只包含少数 的 几行数据)可以使用 结果 集缓存(Result Cache)。
小张做 的 项目与语言处理有点关系,他们把处理 的 结果 也就是字符串保存到在数据库里面,后续需要按照条件把这些数据 查询 出来,但需要对这些字符串做严格 的 区分,也就是说,如果 查询 A字符串,不能把B字符串 查询 出来,哪怕这两个字符串只有一个空格 的 差异 ...假设我们需要 查询 名字为Tom 的 记录(没有空格), SQL 很简单: SELECT * FROM white_space WHERE name = 'Tom'; 然而,让小张大跌眼镜 的 是,上面的 SQL 竟然 返回 两条数据...公司有一套ORM来做这样 的 适配,开发人员只要按照标准来写 SQL 就可以了,但是,如果在 SQL 语句中加上BINARY,切换到 Oracle 数据库就会出错,这可怎么办?!...当然,也可以判断数据库 的 类型,如果是MySQL数据库,就加上BINARY关键字,否则就不加( Oracle 数据库可以严格区分后置空格),但是,这样 的 改动 也太大了,因为MySQL 中 的 语句都完全忽略了后置空格 的 存在...,比如GROUP BY: SELECT name,COUNT(*) FROM white_space GROUP BY name 返回 这样 的 结果 : ?
*这样 的 查询 , 返回 的 数据量越大,这个值也 会 越大。...需要再次强调 的 是,持续 时间 衡量 的 是从 SQL 开始执行即游标打开直到游标被关闭或取消 的 时间 跨度,这意味着如果数据库1分钟内完成一个 查询 ,但随后产生 的 数百万 结果 每次只能 返回 几行,从应用 的 角度看,这个 查询 将需要很长 的 时间 ...例如我通过monitor这个hint强制让 ORACLE 监控这个 SQL ,这个 SQL 会 返回 大量 的 结果 集给客户端,我们通过EMCC来监控这个 SQL 的 相关监控信息: ?...数据库 时间 数据库 时间 即DB Time,显示 的 是一个 查询 在数据库 中 执行花费 的 总 时间 ,就DML操作来说,一般数据库 时间 基本等于持续 时间 ,因为DML操作不用 返回 结果 集,没有网络交互 时间 ,但是如果运行 的 是一个...我们再次看一下上面已经使用过 的 一张图,对于这个 查询 来说,由于要 返回 大量 的 结果 集给客户端,因此持续 时间 远远大于数据库 时间 。 ?
Latch争用 会 增加语句执行 时间 并降低并发性。 软解析是任何不是硬解析 的 解析。 如果提交 的 语句与共享池中 的 可重用 SQL 语句相同,则 Oracle Database将重用现有代码。...这种语义 差异 意味着第二个语句不能重用第一个语句 的 代码。 即使两个语句 在 语义上相同,环境 差异 也 会 导致 难以解析。...3.2 Oracle 数据库如何处理 DML 大多数 DML 语句都有一个 查询 组件。 在 查询 中 ,执行游标会将 查询 结果 放入一组称为 结果 集 的 行 中 。...对于某些 查询 ,数据库会尽快 返回 第一行,而对于其他 查询 ,它会在 返回 第一行之前创建整个 结果 集。...3.2.2 读取一致性 通常, 查询 使用 Oracle 数据库读取一致性机制检索数据,该机制可确保 查询 读取 的 所有数据块与单个 时间 点保持一致。 读取一致性使用 undo 数据来显示过去 的 数据版本。
3、语法 差异 PG中有少数语法不同但功能相同 SQL 。ACS/pg 会 自动进行转换,只有大部分函数不同,需要手工进行转换。这个工作由db_ sql _prep来完成。...Sysdate Oracle 使用sysdate函数获取当前日期和 时间 (以服务器 的 时区为准)。Postgres使用’now’::timestamp作为当前事务启动 的 日期和 时间 。...Postgsql 中 可以将FROM子句丢弃。可以 在 postgres 中 创建一个视图作为这个表从而消除上述问题。这样就可以 在 不干扰Postgres 的 解析器情况下兼容 Oracle 的 SQL 。...(+) (+)表示,如果表b 中 没有匹配 的 item_id值,匹配 会 继续下去, 会 作为一个空行进行匹配。...空字符串与NULL Oracle 中 ,strings()空和NULL 在 字符串内容 中 相同。可以将NULL和和一个字符串连接起来作为 结果 。但是 在 postgres 中 ,这种情况得到 的 结果 是NULL。
下面来查看此 SQL 的 执行计划: 执行计划 中 ,可以看到 在 谓词信息部分有多个 FILTER, 在 执行计划中有3个 FILTER,但是 在 SQL *PLUS 中 ,只有两个 OR,所以需要弄清楚哪些 FILTER...这里有一个判断准则: 当 FILTER 下面有两个儿子表( 结果 集) 的 时候,此时FILTER就是子 查询 没有展开 导致 ,此时 的 FILTER 可以看成是执行完子 查询 后 的 过滤; 当 FILTER 下面只有一个儿子表...下面查看一下主表 返回 的 行数: 这里只简单 的 查询 表 GROUP BY 的 值,这里根据上面的值估计主表 返回 的 结果 集很多,如果要准确 的 值,可以关联上面2张表 查询 。...总结 本条 SQL 优化是通过改写 SQL 来完成 的 ,意味着业务需要修改 SQL ,可能会出现业务修改完 SQL 再上线,这中间可能 会 消耗大量 的 时间 ,并且如果 SQL 后期出现性能问题,需要再次修改 SQL ...近期文章 新年贺礼:云和恩墨大讲堂期刊第二期 删繁就简-云和恩墨 的 一道面试题解析 用 SQL 解一道数学题:Gauss和Poincare 新年贺礼:云和恩墨大讲堂期刊发行 2015 Oracle 十 大 热门文章精选
远远大于 SQL 访问 的 表占用 的 物理大小。所以初步判断 在 执行计划 中 存在某个对象被轮询。...逻辑读比物理读性能好,并且逻辑读消耗 的 时间 很短,但是过高 的 逻辑读 会 带来CPU使用率 的 增加,RAC环境 会 导致 过多 的 GC等待,还有可能 会 影响后来 的 一些TX,INDEX ITL等等待事件 的 出现,前不久就曾经遇到一个逻辑读 导致 ... 在 标量子 查询 中 ,当主 查询 返回 一行数据时,所有的标量子 查询 就要执行一次,如果在连接列有索引时,标量子 查询 在 主表 返回 的 行很少 的 情况下,对性能影响不大,常常出现在OLTP环境,并且连接列一般都有索引;如果在OLAP...环境 中 ,看到标量子 查询 千万要小心,通常,主表 返回 的 行很多,并且子 查询 中 的 表通常在连接列上面无索引, 导致 性能很低下,本案例就是这种情况; 2....12c新特性改进 对于类似以上 的 情况, 在 Oracle Database 12C 中 ,优化器已经可以自动实现等价改写,但是需要注意 的 在 12.1.0.2版本中有BUG,可能 导致 结果 集不准确。
事务 在 修改块时(其实就是 在 修改行) 会 检查行 中 row header 中 的 标志位,如果该标志位为0(该行没有被活动 的 事务锁住),就把该标志位修改为事务 在 该块获得 的 itl 的 序号,这样当前事务就获得了对记录 的 锁定...( 2) 字典定义锁: 用于防止 在 进行字典操作时又进行语法分析,这样可以避免 在 查询 字典 的 同时 改动 某个表 的 结构。...如果此时其他用户对上面 返回 结果 集 的 数据进行dml或ddl操作都会 返回 一个错误信息或发生阻塞。 1:对 返回 结果 集进行update或delete操作会发生阻塞。 左下角 的 时间 执行了很久。 ?...这里面有一种潜在 的 危险就是由于被选出 的 结果 集并没有被锁定,是存在一种可能被其他用户更改 的 可能。因此 Oracle 仍然建议是用悲观封锁,因为这样 会 更安全。...---- Select … for update 当一个用户执行 select..for update 对 返回 的 结果 集进行修改时,如 果 结果 集已经被另一个会话锁定,此时 Oracle 已经对 返回 的 结果 集上加了排它 的 行级锁
也就是说 在 本次测试 中 ,10g,外层 查询 不进行t1和t2 的 扫描,直接 返回 结果 了,而12c,外层 查询 还要进行t1表和t2表层扫描才 返回 结果 。 那究竟是不是版本 的 差异 呢?...这其实不是10g和12c 的 差别,而是not exists 的 返回 数据对外层 的 影响。子 查询 要 返回 0行记录,才满足not exist 的 条件,从而 返回 外层 查询 结果 。... 在 10g 中 ,子 查询 返回 了一行记录 不满足not exists(即0行才满足),所以,也就不用在外层继续 查询 了。直接 返回 记录0行。... 在 12c 中 ,子 查询 返回 0行记录,满足not exist 的 条件,所以还需要在外层 查询 中继续 查询 。 正是这一行记录 的 差异 , 导致 了not exists对外层 查询 的 影响。...进而 导致 整个 sql 的 buffer get 的 差异 。 反证这个 结果 ,我只要在12c 中 ,运行子 查询 结果 返回 大于0行 的 ,不满足not exists,也应该不会去外层 查询 了。
不过这个案例存在一点小 的 瑕疵,因为如果一不小心,很可能 会 导致 结果 与预期不符,这是因为这里有一个例外存在。...再介绍一下OPEN CURSOR, Oracle 中 当一个游标被打开,其 结果 集就已经确定了,也就是说这个游标会根据OPEN CURSOR这个 时间 点对应 的 SCN来构造一致性 查询 。...使用这种办法可以模拟一个 大 的 查询 ,OPEN CURSOR相当于 大 的 查询 的 开始 时间 ,其早于其他会话 的 修改提交 时间 ,而FETCH 的 时间 相当于 大 查询 读取到这条记录 的 时间 ,而该 时间 晚于其他会话提交 的 时间 :