问题描述
嗨,
您好!
1.第一次,在同一会话中执行查询,它以良好的计划快速完成。
2.第二次,在同一会话中执行相同的查询,立即挂起并选择不同的计划。
a) 你能建议一下计划突然改变的原因是什么吗?
两次运行之间的基础表分区中没有数据更改。
b) 这个查询可以进一步调整吗?
PRCING_DATE是两个表中的分区键列。
您好!
1.第一次,在同一会话中执行查询,它以良好的计划快速完成。
2.第二次,在同一会话中执行相同的查询,立即挂起并选择不同的计划。
a) 你能建议一下计划突然改变的原因是什么吗?
两次运行之间的基础表分区中没有数据更改。
b) 这个查询可以进一步调整吗?
PRCING_DATE是两个表中的分区键列。
SQL> WITH LAST_TICKS_BY_DAY AS ( SELECT /*+ gather_plan_statistics */ MAX(LAST_PRICE_TIME) AS LAST_PRICE_TIME, MAX(PRICING_DATE) AS PRICING_DATE FROM TEST.FFINC_PRC A WHERE A.INSTRUMENT_ID = 9730862 AND A.PRICING_DATE BETWEEN TO_DATE('2020-07-28', 'YYYY-MM-DD') AND TO_DATE('2020-07-29', 'YYYY-MM-DD') AND LAST_PRICE_TIME >= TO_TIMESTAMP('28-JUL-20 11.59.59.000000000 PM','DD-MON-YY HH.MI.SS.FF PM') AND LAST_PRICE_TIME <= TO_TIMESTAMP('29-JUL-20 11.59.59.000000000 PM','DD-MON-YY HH.MI.SS.FF PM') AND A.PRICE_TYPE_ID in(5 , 6 ) GROUP BY TRUNC(LAST_PRICE_TIME) ) SELECT /*+ gather_plan_statistics */ p.INSTRUMENT_ID, p.SOURCE, p.BID_PRICE, p.LAST_PRICE_TIME, p.ASK_PRICE, p.MID_PRICE, p.BID_SPREAD, p.ASK_SPREAD, p.MID_SPREAD, p.BID_YIELD, p.ASK_YIELD, p.MID_YIELD, p.ASK_SPREAD_CURVE, p.T_SPREAD, p.MID_T_ 4 SPREAD, p.ASK_T_SPREAD, p.TEST_CONDITION_CODE, p.CURVE_YIELD, p.PRICE_TYPE, p.BID_SPREAD_CURVE, p.MID_SPREAD_CURVE, p.PRICE_TYPE_ID, p.BID_DISCOUNT_RATE, p.ASK_DISCOUNT_RATE, p.EOD_LATE_BID_PRICE_DELTA, p.SPREAD, a.PRICING_SPREAD_TYPE, a.BENCHMARK_NAME, a.TBA_BACK_BENCH, a.DIMINIMIS_ELIGIBLE_FLAG, a.HALF_DEMINIMIS_ELIGIBLE_FLAG, a.BENCHMARK_TBA, a.PAYUP FROM TEST.FFINC_PRC p LEFT JOIN TEST.FPRC_ASSUM a ON p.ASSUMP_ID = a.ASSUMP_ID JOIN LAST_TICKS_BY_DAY B ON P.LAST_PRICE_TIME = B.LAST_PRICE_TIME WHERE p.INSTRUMENT_ID = 9730862 AND p.PRICING_DATE = B.PRICING_DATE AND p.PRICE_TYPE_ID in(5, 6) ORDER BY A.LAST_PRICE_TIME ASC / Elapsed: 00:00:00.09 SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST')); PLAN_TABLE_OUTPUT ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------ SQL_ID 4suz6vatc44ts, child number 0 ------------------------------------- WITH LAST_TICKS_BY_DAY AS ( SELECT /*+ gather_plan_statistics */ MAX(LAST_PRICE_TIME) AS LAST_PRICE_TIME, MAX(PRICING_DATE) AS PRICING_DATE FROM TEST.FFINC_PRC A WHERE A.INSTRUMENT_ID = 9730862 AND A.PRICING_DATE BETWEEN TO_DATE('2020-07-28', 'YYYY-MM-DD') AND TO_DATE('2020-07-29', 'YYYY-MM-DD') AND LAST_PRICE_TIME >= TO_TIMESTAMP('28-JUL-20 11.59.59.000000000 PM','DD-MON-YY HH.MI.SS.FF PM') AND LAST_PRICE_TIME <= TO_TIMESTAMP('29-JUL-20 11.59.59.000000000 PM','DD-MON-YY HH.MI.SS.FF PM') AND A.PRICE_TYPE_ID in(5 , 6 ) GROUP BY TRUNC(LAST_PRICE_TIME) ) SELECT /*+ gather_plan_statistics */ p.INSTRUMENT_ID, p.SOURCE, p.BID_PRICE, p.LAST_PRICE_TIME, p.ASK_PRICE, p.MID_PRICE, p.BID_SPREAD, p.ASK_SPREAD, p.MID_SPREAD, p.BID_YIELD, p.ASK_YIELD, p.MID_YIELD, p.ASK_SPREAD_CURVE, p.T_SPREAD, p.MID_T_SPREAD, p.ASK_T_SPREAD, p.TEST_CONDITION_CODE, p.CURVE_YIELD, p.PRICE_TYPE, p.BID_SPREAD_CURVE, p.MID_SPREAD_CURVE, p.PRICE_TYPE_ID, p.BID Plan hash value: 86494900 ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.06 | 11512 | | | | | 1 | SORT ORDER BY | | 1 | 1 | 1 |00:00:00.06 | 11512 | 2048 | 2048 | 2048 (0)| | 2 | NESTED LOOPS OUTER | | 1 | 1 | 1 |00:00:00.06 | 11512 | | | | | 3 | NESTED LOOPS | | 1 | 1 | 1 |00:00:00.06 | 11506 | | | | | 4 | VIEW | | 1 | 1 | 1 |00:00:00.06 | 11497 | | | | | 5 | HASH GROUP BY | | 1 | 1 | 1 |00:00:00.06 | 11497 | 2456K| 2456K| 1291K (0)| | 6 | PARTITION RANGE ITERATOR | | 1 | 1 | 6272 |00:00:00.05 | 11497 | | | | | 7 | INLIST ITERATOR | | 2 | | 6272 |00:00:00.05 | 11497 | | | | |* 8 | TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| FFINC_PRC | 4 | 1 | 6272 |00:00:00.05 | 11497 | | | | | 9 | SORT CLUSTER BY ROWID | | 4 | 1 | 6272 |00:00:00.01 | 50 | 4096 | 4096 | 2048 (0)| |* 10 | INDEX RANGE SCAN | FF_INC_PRICE_IDX1 | 4 | 1 | 6272 |00:00:00.01 | 50 | 1025K| 1025K| | | 11 | PARTITION RANGE ITERATOR | | 1 | 1 | 1 |00:00:00.01 | 9 | | | | | 12 | INLIST ITERATOR | | 1 | | 1 |00:00:00.01 | 9 | | | | |* 13 | TABLE ACCESS BY LOCAL INDEX ROWID BATCHED | FFINC_PRC | 2 | 1 | 1 |00:00:00.01 | 9 | | | | |* 14 | INDEX RANGE SCAN | FF_INC_PRICE_IDX1 | 2 | 1 | 1 |00:00:00.01 | 8 | 1025K| 1025K| | | 15 | TABLE ACCESS BY GLOBAL INDEX ROWID | FPRC_ASSUM | 1 | 1 | 1 |00:00:00.01 | 6 | | | | |* 16 | INDEX UNIQUE SCAN | FPRC_ASSUM_PK | 1 | 1 | 1 |00:00:00.01 | 5 | 1025K| 1025K| | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 8 - filter("A"."PRICING_DATE"<=TO_DATE(' 2020-07-29 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) 10 - access((("A"."PRICE_TYPE_ID"=5 OR "A"."PRICE_TYPE_ID"=6)) AND "A"."INSTRUMENT_ID"=9730862 AND "LAST_PRICE_TIME">=TO_TIMESTAMP('28-JUL-20 11.59.59.000000000 PM','DD-MON-YY HH.MI.SS.FF AM') AND "LAST_PRICE_TIME"<=TO_TIMESTAMP('29-JUL-20 11.59.59.000000000 PM','DD-MON-YY HH.MI.SS.FF AM')) 13 - filter("P"."PRICING_DATE"="B"."PRICING_DATE") 14 - access((("P"."PRICE_TYPE_ID"=5 OR "P"."PRICE_TYPE_ID"=6)) AND "P"."INSTRUMENT_ID"=9730862 AND "P"."LAST_PRICE_TIME"="B"."LAST_PRICE_TIME") 16 - access("P"."ASSUMP_ID"="A"."ASSUMP_ID") 53 rows selected. Elapsed: 00:00:00.02 SQL> WITH LAST_TICKS_BY_DAY AS ( SELECT /*+ gather_plan_statistics */ MAX(LAST_PRICE_TIME) AS LAST_PRICE_TIME, MAX(PRICING_DATE) AS PRICING_DATE FROM TEST.FFINC_PRC A WHERE A.INSTRUMENT_ID = 9730862 AND A.PRICING_DATE BETWEEN TO_DATE('2020-07-28', 'YYYY-MM-DD') AND TO_DATE('2020-07-29', 'YYYY-MM-DD') AND LAST_PRICE_TIME >= TO_TIMESTAMP('28-JUL-20 11.59.59.000000000 PM','DD-MON-YY HH.MI.SS.FF PM') AND LAST_PRICE_TIME <= TO_TIMESTAMP('29-JUL-20 11.59.59.000000000 PM','DD-MON-YY HH.MI.SS.FF PM') AND A.PRICE_TYPE_ID in(5 , 6 ) GROUP BY TRUNC(LAST_PRICE_TIME) ) SELECT /*+ gather_plan_statistics */ p.INSTRUMENT_ID, p.SOURCE, p.BID_PRICE, p.LAST_PRICE_TIME, p.ASK_PRICE, p.MID_PRICE, p.BID_SPREAD, p.A 2 SK_SPREAD, p.MID_SPREAD, p.BID_YIELD, p.ASK_YIELD, p.MID_YIELD, p.ASK_SPREAD_CURVE, p.T_SPREAD, p.MID_T_SPREAD, p.ASK_T_SPREAD, p.TEST_CONDITION_CODE, p.CURVE_YIELD, p.PRICE_TYPE, p.BID_SPREAD_CURVE, p.MID_SPREAD_CURVE, p.PRICE_TYPE_ID, p.BI 3 D_DISCOUNT_RATE, p.ASK_DISCOUNT_RATE, p.EOD_LATE_BID_PRICE_DELTA, p.SPREAD, a.PRICING_SPREAD_TYPE, a.BENCHMARK_NAME, a.TBA_BACK_BENCH, a.DIMINIMIS_ELIGIBLE_FLAG, a.HALF_DEMINIMIS_ELIGIBLE_FLAG, a.BENCHMARK_TBA, a.PAYUP 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 FROM TEST.FFINC_PRC p LEFT JOIN TEST.FPRC_ASSUM a ON p.ASSUMP_ID = a.ASSUMP_ID JOIN LAST_TICKS_BY_DAY B ON P.LAST_PRICE_TIME = B.LAST_PRICE_TIME WHERE p.INSTRUMENT_ID = 9730862 AND p.PRICING_DATE = B.PRICING_DATE AND p.PRICE_TYPE_ID in(5, 6) ORDER BY A.LAST_PRICE_TIME ASC / 19 20 21 22 23 24 25 26 27 ^CWITH LAST_TICKS_BY_DAY AS ( * ERROR at line 1: ORA-01013: user requested cancel of current operation Elapsed: 00:18:42.80 SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST')); PLAN_TABLE_OUTPUT ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------ SQL_ID 4suz6vatc44ts, child number 1 ------------------------------------- WITH LAST_TICKS_BY_DAY AS ( SELECT /*+ gather_plan_statistics */ MAX(LAST_PRICE_TIME) AS LAST_PRICE_TIME, MAX(PRICING_DATE) AS PRICING_DATE FROM TEST.FFINC_PRC A WHERE A.INSTRUMENT_ID = 9730862 AND A.PRICING_DATE BETWEEN TO_DATE('2020-07-28', 'YYYY-MM-DD') AND TO_DATE('2020-07-29', 'YYYY-MM-DD') AND LAST_PRICE_TIME >= TO_TIMESTAMP('28-JUL-20 11.59.59.000000000 PM','DD-MON-YY HH.MI.SS.FF PM') AND LAST_PRICE_TIME <= TO_TIMESTAMP('29-JUL-20 11.59.59.000000000 PM','DD-MON-YY HH.MI.SS.FF PM') AND A.PRICE_TYPE_ID in(5 , 6 ) GROUP BY TRUNC(LAST_PRICE_TIME) ) SELECT /*+ gather_plan_statistics */ p.INSTRUMENT_ID, p.SOURCE, p.BID_PRICE, p.LAST_PRICE_TIME, p.ASK_PRICE, p.MID_PRICE, p.BID_SPREAD, p.ASK_SPREAD, p.MID_SPREAD, p.BID_YIELD, p.ASK_YIELD, p.MID_YIELD, p.ASK_SPREAD_CURVE, p.T_SPREAD, p.MID_T_SPREAD, p.ASK_T_SPREAD, p.TEST_CONDITION_CODE, p.CURVE_YIELD, p.PRICE_TYPE, p.BID_SPREAD_CURVE, p.MID_SPREAD_CURVE, p.PRICE_TYPE_ID, p.BID Plan hash value: 2213069938 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 0 |00:00:00.01 | 0 | 0 | | | | | 1 | SORT ORDER BY | | 1 | 1 | 0 |00:00:00.01 | 0 | 0 | 73728 | 73728 | | | 2 | NESTED LOOPS OUTER | | 1 | 1 | 0 |00:00:00.01 | 0 | 0 | | | | |* 3 | HASH JOIN | | 1 | 1 | 0 |00:00:00.01 | 0 | 0 | 2991K| 2991K| 1694K (0)| | 4 | VIEW | | 1 | 6271 | 1 |00:00:00.05 | 11352 | 0 | | | | | 5 | HASH GROUP BY | | 1 | 6271 | 1 |00:00:00.05 | 11352 | 0 | 2456K| 2456K| 1288K (0)| | 6 | PARTITION RANGE ITERATOR | | 1 | 6272 | 6272 |00:00:00.04 | 11352 | 0 | | | | | 7 | INLIST ITERATOR | | 2 | | 6272 |00:00:00.04 | 11352 | 0 | | | | |* 8 | TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| FFINC_PRC | 4 | 6272 | 6272 |00:00:00.04 | 11352 | 0 | | | | | 9 | SORT CLUSTER BY ROWID | | 4 | 34 | 6272 |00:00:00.01 | 50 | 0 | 96256 | 96256 |43008 (0)| |* 10 | INDEX RANGE SCAN | FF_INC_PRICE_IDX1 | 4 | 34 | 6272 |00:00:00.01 | 50 | 0 | 1025K| 1025K| | | 11 | PARTITION RANGE ALL | | 1 | 13931 | 2529K|00:20:16.16 | 1302K| 1038K| | | | | 12 | INLIST ITERATOR | | 889 | | 2529K|00:20:42.40 | 1302K| 1038K| | | | | 13 | TABLE ACCESS BY LOCAL INDEX ROWID BATCHED | FFINC_PRC | 1777 | 13931 | 2529K|00:20:44.74 | 1302K| 1038K| | | | |* 14 | INDEX RANGE SCAN | FF_INC_PRICE_IDX1 | 1497 | 13931 | 2529K|00:00:09.91 | 28025 | 19080 | 1025K| 1025K| | | 15 | TABLE ACCESS BY GLOBAL INDEX ROWID | FPRC_ASSUM | 0 | 1 | 0 |00:00:00.01 | 0 | 0 | | | | |* 16 | INDEX UNIQUE SCAN | FPRC_ASSUM_PK | 0 | 1 | 0 |00:00:00.01 | 0 | 0 | 1025K| 1025K| | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("P"."PRICING_DATE"="B"."PRICING_DATE" AND "P"."LAST_PRICE_TIME"="B"."LAST_PRICE_TIME") 8 - filter("A"."PRICING_DATE"<=TO_DATE(' 2020-07-29 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) 10 - access((("A"."PRICE_TYPE_ID"=5 OR "A"."PRICE_TYPE_ID"=6)) AND "A"."INSTRUMENT_ID"=9730862 AND "LAST_PRICE_TIME">=TO_TIMESTAMP('28-JUL-20 11.59.59.000000000 PM','DD-MON-YY HH.MI.SS.FF AM') AND "LAST_PRICE_TIME"<=TO_TIMESTAMP('29-JUL-20 11.59.59.000000000 PM','DD-MON-YY HH.MI.SS.FF AM')) 14 - access((("P"."PRICE_TYPE_ID"=5 OR "P"."PRICE_TYPE_ID"=6)) AND "P"."INSTRUMENT_ID"=9730862) 16 - access("P"."ASSUMP_ID"="A"."ASSUMP_ID") Note ----- - statistics feedback used for this statement 57 rows selected.复制
专家解答
差异原因的线索是第二个方案底部的这条线:
这意味着优化器发现它的估计第一次出错,并采取措施进行调整。
这很可能是因为步骤6-10在第一个计划估计1行,但返回超过6,000!
请注意,在第二个计划中,第6-8行具有正确的估计值,第8-9行具有多个估计值。
问题是,它已经将这些新的估计值通过以上的方式提交给了该集团-does返回一行。这导致优化器在步骤3使用哈希连接,而不是嵌套循环。
这意味着它不能再在步骤13应用此过滤器:
因此,无需快速读取一行,而是需要20分钟才能读取FFINC_PRC中的所有分区。
确保OPTIMIZER_ADAPTIVE_STATISTICS为FALSE将减少这种情况的变化。
在某些情况下,当禁用此功能时,统计信息反馈仍然会发生,但是这样做可能足以阻止您看到的完整的重新估计。
Can this query be tuned any further ?
我看到查询读取FFINC_PRC两次。在我看来,子查询是查找最近的行,然后您将其重新加入以获取详细信息。
您应该能够读取表一次,使用分析函数查找最大值/获取行号,例如:
或获取每个列的最大值,并过滤到外部查询中与这些列匹配的行。
- statistics feedback used for this statement复制
这意味着优化器发现它的估计第一次出错,并采取措施进行调整。
这很可能是因为步骤6-10在第一个计划估计1行,但返回超过6,000!
请注意,在第二个计划中,第6-8行具有正确的估计值,第8-9行具有多个估计值。
问题是,它已经将这些新的估计值通过以上的方式提交给了该集团-does返回一行。这导致优化器在步骤3使用哈希连接,而不是嵌套循环。
这意味着它不能再在步骤13应用此过滤器:
13 - filter("P"."PRICING_DATE"="B"."PRICING_DATE")复制
因此,无需快速读取一行,而是需要20分钟才能读取FFINC_PRC中的所有分区。
确保OPTIMIZER_ADAPTIVE_STATISTICS为FALSE将减少这种情况的变化。
在某些情况下,当禁用此功能时,统计信息反馈仍然会发生,但是这样做可能足以阻止您看到的完整的重新估计。
Can this query be tuned any further ?
我看到查询读取FFINC_PRC两次。在我看来,子查询是查找最近的行,然后您将其重新加入以获取详细信息。
您应该能够读取表一次,使用分析函数查找最大值/获取行号,例如:
with rws as ( select f.*, row_number () over ( order by pricing_date desc, last_price_time desc ) rn from ffinc_prc f where ... ) select * from rws where rn = 1;复制
或获取每个列的最大值,并过滤到外部查询中与这些列匹配的行。
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
Oracle DataGuard高可用性解决方案详解
孙莹
573次阅读
2025-03-26 23:27:33
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
532次阅读
2025-04-15 17:24:06
【纯干货】Oracle 19C RU 19.27 发布,如何快速升级和安装?
Lucifer三思而后行
435次阅读
2025-04-18 14:18:38
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
430次阅读
2025-04-08 09:12:48
【ORACLE】记录一些ORACLE的merge into语句的BUG
DarkAthena
427次阅读
2025-04-22 00:20:37
墨天轮个人数说知识点合集
JiekeXu
427次阅读
2025-04-01 15:56:03
Oracle SQL 执行计划分析与优化指南
Digital Observer
425次阅读
2025-04-01 11:08:44
【ORACLE】你以为的真的是你以为的么?--ORA-38104: Columns referenced in the ON Clause cannot be updated
DarkAthena
404次阅读
2025-04-22 00:13:51
Oracle数据库一键巡检并生成HTML结果,免费脚本速来下载!
陈举超
391次阅读
2025-04-20 10:07:02
Oracle 19c RAC更换IP实战,运维必看!
szrsu
365次阅读
2025-04-08 23:57:08