一次ORACLE SQL谓词跨界导致的执行计划不准

简介: 一次ORACLE SQL谓词跨界导致的执行计划不准 首先说明谓词跨界一般出现在日期类型中,打个比方你的统计数据是8月20号的,但是今天是8月28日,在这20号到28号之间日期是没有进入统计数据的, 这样可能导致,根据统计信息计算出来的COST异常的小,这样可能导致本来该走其他字段索引的语句走到时间索引上去,导致执行计划最终错误。
一次ORACLE SQL谓词跨界导致的执行计划不准


首先说明谓词跨界一般出现在日期类型中,打个比方你的统计数据是8月20号的,但是今天是8月28日,在这20号到28号之间日期是没有进入统计数据的,
这样可能导致,根据统计信息计算出来的COST异常的小,这样可能导致本来该走其他字段索引的语句走到时间索引上去,导致执行计划最终错误。
在10053中可以看到如下提示:


as selectvity of out-of-range/non-existent value pred


以前多次遇到过,今天再次遇到,就记录于此,如下SQL
select *
from test
where seller_user_id = '123'
and raw_add_time >= trunc(sysdate-1, 'mi')
and raw_add_time < trunc(sysdate, 'mi')


其执行计算如下:
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2023568823
--------------------------------------------------------------------------------
| Id  | Operation                    | Name                   | Rows  | Bytes |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                        |     1 |   574 |
|*  1 |  FILTER                      |                        |       |       |
|*  2 |   TABLE ACCESS BY INDEX ROWID| TEST                   |     1 |   574 |
|*  3 |    INDEX RANGE SCAN          | TEST_ADD_TIME_INDEX    |     2 |       |
--------------------------------------------------------------------------------
这里test_ADD_TIME_INDEX就是我的时间上的索引,通过查看选择率后发现seller_user_id远远
小于raw_add_time范围的选择率,应该走到seller_user_id上的索引才对,这里可能发生了
谓词跨界查看其统计数据发现是7月20号的,今天是8月28日。然后进行了一下验证


调整时间后
select *
from test
where seller_user_id = '123'
and raw_add_time >= trunc(sysdate-100, 'mi')
and raw_add_time < trunc(sysdate-99, 'mi')




PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 576270446
--------------------------------------------------------------------------------
| Id  | Operation                    | Name                 | Rows  | Bytes | Cos
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                      |     1 |   574 |
|*  1 |  FILTER                      |                      |       |       |
|*  2 |   TABLE ACCESS BY INDEX ROWID| TEST_BASE_INFO       |     1 |   574 |
|*  3 |    INDEX RANGE SCAN          | TEST_ID_INDEX |    23 |       |
--------------------------------------------------------------------------------


这里更改了时间范围在已知的统计数据范围内,执行计划正确。


我们进行10053 TRACE验证:


SINGLE TABLE ACCESS PATH 
  Single Table Cardinality Estimation for TEST[TEST] 
  Column (#14): 
    NewDensity:0.000001, OldDensity:0.000623 BktCnt:254, PopBktCnt:79, PopValCnt:7, NDV:814912
  Column (#14): SELLER_USER_ID(
    AvgLen: 21 NDV: 814912 Nulls: 855565 Density: 0.000001
    Histogram: HtBal  #Bkts: 254  UncompBkts: 254  EndPtVals: 183


  Column (#41): RAW_ADD_TIME(
    AvgLen: 8 NDV: 13533184 Nulls: 0 Density: 0.000000 Min: 2454768 Max: 2457225
  Using prorated density: 0.000000 of col #41 as selectvity of out-of-range/non-existent value pred //谓词跨界
  Table: TEST  Alias: TEST
    Card: Original: 27510606.000000  Rounded: 1  Computed: 0.00  Non Adjusted: 0.00
  Access Path: TableScan
    Cost:  618899.27  Resp: 618899.27  Degree: 0
      Cost_io: 616819.00  Cost_cpu: 43729541941
      Resp_io: 616819.00  Resp_cpu: 43729541941
  Using prorated density: 0.000000 of col #41 as selectvity of out-of-range/non-existent value pred //谓词跨界
  Access Path: index (RangeScan)
    Index: TEST_ADD_TIME_INDEX 
    resc_io: 5.00  resc_cpu: 39819
    ix_sel: 0.000000  ix_sel_with_filters: 0.000000 
    Cost: 5.00  Resp: 5.00  Degree: 1
 
 谓词跨界后选择率成为了0.000000,这样导致了执行计划错误。
 解决也很简单,按需求重新收集统计信息即可
 
相关文章
|
8天前
|
SQL
【YashanDB 知识库】使用 leading hint 调整 SQL 执行计划后报错 YAS-04522 invalid hint leading
在 YashanDB 的所有版本中,使用 leading hint 调整 SQL 执行计划时可能出现“YAS-04522 invalid hint leading”错误,导致 SQL 无法正常执行。原因是 YashanDB 优化器的 Bug。解决方法为避免使用 leading hint。可通过创建测试表 a、b、c 并执行特定 SQL 语句来验证问题是否存在。
MySQL原理简介—10.SQL语句和执行计划
本文介绍了MySQL执行计划的相关概念及其优化方法。首先解释了什么是执行计划,它是SQL语句在查询时如何检索、筛选和排序数据的过程。接着详细描述了执行计划中常见的访问类型,如const、ref、range、index和all等,并分析了它们的性能特点。文中还探讨了多表关联查询的原理及优化策略,包括驱动表和被驱动表的选择。此外,文章讨论了全表扫描和索引的成本计算方法,以及MySQL如何通过成本估算选择最优执行计划。最后,介绍了explain命令的各个参数含义,帮助理解查询优化器的工作机制。通过这些内容,读者可以更好地理解和优化SQL查询性能。
MySQL进阶突击系列(07) 她气鼓鼓递来一条SQL | 怎么看执行计划、SQL怎么优化?
在日常研发工作当中,系统性能优化,从大的方面来看主要涉及基础平台优化、业务系统性能优化、数据库优化。面对数据库优化,除了DBA在集群性能、服务器调优需要投入精力,我们研发需要负责业务SQL执行优化。当业务数据量达到一定规模后,SQL执行效率可能就会出现瓶颈,影响系统业务响应。掌握如何判断SQL执行慢、以及如何分析SQL执行计划、优化SQL的技能,在工作中解决SQL性能问题显得非常关键。
如何在 Oracle 中配置和使用 SQL Profiles 来优化查询性能?
在 Oracle 数据库中,SQL Profiles 是优化查询性能的工具,通过提供额外统计信息帮助生成更有效的执行计划。配置和使用步骤包括:1. 启用自动 SQL 调优;2. 手动创建 SQL Profile,涉及收集、执行调优任务、查看报告及应用建议;3. 验证效果;4. 使用 `DBA_SQL_PROFILES` 视图管理 Profile。
Oracle SQL性能优化全面指南
在数据库管理领域,Oracle SQL性能优化是确保数据库高效运行和数据查询速度的关键
Oracle数据库SQL语句详解与应用指南
在数字化时代,数据库已成为各类企业和组织不可或缺的核心组件。Oracle数据库作为业界领先的数据库管理系统之一,广泛应用于各种业务场景。掌握Oracle数据库的SQL语句是数据库管理员、开发人员及运维人员的基本技能。本文将详细介绍Oracle数据库SQL语句的基本概念、语法、应用及最佳实践。一、Or
146 3
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
7月前
|
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
617 0
|
8月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
116 9

热门文章

最新文章

推荐镜像

更多
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等