问题描述
嗨,汤姆,
我们有一张表,有大约700个分区。
我们的测试查询是
当我们解释这个查询的计划时,这个计划是正确的。它直接进入分区 #697 (修剪),然后使用索引FS_1D_IDX2。
但是当我们实际执行查询时,Oracle没有使用上面解释的计划。
实际执行计划就好像没有提供实际的文字值一样。
我们有一张表,有大约700个分区。
我们的测试查询是
select count(*) from fs_1d f where f.fs_date = '03-JAN-2017' and f.feed_code = 'E4F1'复制
当我们解释这个查询的计划时,这个计划是正确的。它直接进入分区 #697 (修剪),然后使用索引FS_1D_IDX2。
SQL> explain plan for 2 select count(*) 3 from fs_1d f 4 where f.fs_date = '03-JAN-2017' 5 and f.feed_code = 'E4F1' 6 ; Explained. Elapsed: 00:00:00.02 SQL> SELECT * FROM TABLE(dbms_xplan.display); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Pstart| Pstop | ------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 14 | 1112 (0)| | | | 1 | SORT AGGREGATE | | 1 | 14 | | | | | 2 | PARTITION RANGE SINGLE | | 1189 | 16646 | 1112 (0)| 697 | 697 | |* 3 | TABLE ACCESS BY LOCAL INDEX ROWID| FS_1D | 1189 | 16646 | 1112 (0)| 697 | 697 | |* 4 | INDEX RANGE SCAN | FS_1D_IDX2 | 7392 | | 109 (0)| 697 | 697 | ------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - filter("F"."FS_DATE"=TO_DATE(' 2017-01-03 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) 4 - access("F"."FEED_CODE"='E4F1') 20 rows selected. Elapsed: 00:00:00.07复制
但是当我们实际执行查询时,Oracle没有使用上面解释的计划。
SQL> select count(*) 2 from fs_1d f 3 where f.fs_date = '03-JAN-2017' 4 and f.feed_code = 'E4F1' 5 ; COUNT(*) ---------- 240345 Elapsed: 00:09:49.21 SQL> SELECT sql_id, piece, sql_text 2 FROM v$sqltext 3 WHERE sql_id = 'fx1ugkqm3hx5q' 4 ORDER BY piece 5 ; SQL_ID PIECE SQL_TEXT ------------- ---------- ---------------------------------------------------------------- fx1ugkqm3hx5q 0 select count(*) from fs_1d f where f.fs_date = :"SYS_B_0" and f fx1ugkqm3hx5q 1 .feed_code = :"SYS_B_1" Elapsed: 00:00:00.04 SQL> SELECT 2 id, depth, 3 operation, options, 4 object_type, object_owner, object_name, 5 cardinality, bytes, cost 6 FROM v$sql_plan_statistics_all 7 WHERE sql_id = 'fx1ugkqm3hx5q' 8 ORDER BY id 9 ; ID DEPTH OPERATION OPTIONS OBJECT_TYP OBJECT_OWN OBJECT_NAM CARDINALITY BYTES COST ---- ----- -------------------- ---------- ---------- ---------- ---------- ----------- ---------- ---------- 0 0 SELECT STATEMENT 1096697 1 1 SORT AGGREGATE 1 14 2 2 VIEW VIEW VW_TE_2 125 1096697 3 3 UNION-ALL 4 4 PARTITION RANGE SINGLE 119 1666 1096697 5 5 TABLE ACCESS FULL TABLE OCFGMR_P FS_1D 119 1666 1096697 6 4 PARTITION RANGE SINGLE 6 84 1096696 7 5 TABLE ACCESS FULL TABLE OCFGMR_P FS_1D 6 84 1096696 8 rows selected. Elapsed: 00:00:00.04复制
实际执行计划就好像没有提供实际的文字值一样。
SQL> explain plan for 2 select count(*) 3 from fs_1d f 4 where f.fs_date = :d1 5 and f.feed_code = 'E4F1' 6 ; Explained. Elapsed: 00:00:00.04 SQL> SELECT * FROM TABLE(dbms_xplan.display); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Pstart| Pstop | ------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 12 | 23544 (1)| | | | 1 | SORT AGGREGATE | | 1 | 12 | | | | | 2 | VIEW | VW_TE_2 | 1309 | | 23544 (1)| | | | 3 | UNION-ALL | | | | | | | | 4 | PARTITION RANGE SINGLE| | 1247 | 14964 | 23544 (1)| KEY | KEY | |* 5 | TABLE ACCESS FULL | FS_1D | 1247 | 14964 | 23544 (1)| KEY | KEY | | 6 | PARTITION RANGE SINGLE| | 62 | 744 | 23544 (1)| KEY | KEY | |* 7 | TABLE ACCESS FULL | FS_1D | 62 | 744 | 23544 (1)| KEY | KEY | ------------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 5 - filter("F"."FEED_CODE"='E4F1' AND ("F"."FS_DATE"=TO_DATE(' 2016-07-30 00:00:00', 'syyyy-mm-dd hh24:mi:ss') OR "F"."FS_DATE">=TO_DATE(' 2016-07-23 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "F"."FS_DATE" =TO_DATE(' 2016-07-19 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "F"."FS_DATE" =TO_DATE(' 2016-07-25 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "F"."FS_DATE"
我们从这个测试用例中得到的问题:
(1) 为什么Oracle解释计划和实际计划会有所不同 (共享池很干净,因为我们在此测试之前进行了新的冲洗)
(2) 为什么Oracle不进行peek并使用查询中提供的文字值,而是对实际计划使用绑定。
对这两个问题有什么见解和建议吗?
非常感谢
复制
专家解答
1) 当我看到
f.fs_date = :"SYS_B_0"
它告诉我你启用了光标共享。所以你所有的文字都将被绑定取代。
2) 我们在 “真正的” 执行过程中窥视绑定。如果您运行 “解释计划” 命令,那么我们 * 不会 * 偷看绑定。这就是为什么解释计划命令可以对你 “撒谎”。
但是光标共享 ....那不是一个有趣的地方 :-)
f.fs_date = :"SYS_B_0"
它告诉我你启用了光标共享。所以你所有的文字都将被绑定取代。
2) 我们在 “真正的” 执行过程中窥视绑定。如果您运行 “解释计划” 命令,那么我们 * 不会 * 偷看绑定。这就是为什么解释计划命令可以对你 “撒谎”。
但是光标共享 ....那不是一个有趣的地方 :-)
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
603次阅读
2025-04-15 17:24:06
【纯干货】Oracle 19C RU 19.27 发布,如何快速升级和安装?
Lucifer三思而后行
588次阅读
2025-04-18 14:18:38
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
496次阅读
2025-04-08 09:12:48
Oracle数据库一键巡检并生成HTML结果,免费脚本速来下载!
陈举超
479次阅读
2025-04-20 10:07:02
【ORACLE】记录一些ORACLE的merge into语句的BUG
DarkAthena
464次阅读
2025-04-22 00:20:37
Oracle 19c RAC更换IP实战,运维必看!
szrsu
440次阅读
2025-04-08 23:57:08
【ORACLE】你以为的真的是你以为的么?--ORA-38104: Columns referenced in the ON Clause cannot be updated
DarkAthena
438次阅读
2025-04-22 00:13:51
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
429次阅读
2025-04-17 17:02:24
火焰图--分析复杂SQL执行计划的利器
听见风的声音
371次阅读
2025-04-17 09:30:30
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
361次阅读
2025-04-15 14:48:05