如图1所示,有t1,t3两个表,t1 没有任何索引,t3 的 CREATION_TIME 字段有索引,t1 left join t3 ,看执行计划是走了 t3的索引的,但是如图2所示,通过新建了一个和 t1 一模一样的表 t1_0320;然后如图三所示,将t1_0320 替换掉t1,其他代码都没变,sql就没走索引了,请问是为什么?另外图4中的关联条件,有其他的写法 可以执行的更快些吗?
请大家帮忙看下,谢谢
如图1所示,有t1,t3两个表,t1 没有任何索引,t3 的 CREATION_TIME 字段有索引,t1 left join t3 ,看执行计划是走了 t3的索引的,但是如图2所示,通过新建了一个和 t1 一模一样的表 t1_0320;然后如图三所示,将t1_0320 替换掉t1,其他代码都没变,sql就没走索引了,请问是为什么?另外图4中的关联条件,有其他的写法 可以执行的更快些吗?
请大家帮忙看下,谢谢
引自免费微信小程序:皆我百晓生
根据提供的信息,看起来在图1中,SQL查询使用了ODS_FDC_EES_ANALYTICS_LINK
表的CREATION_TIME
字段上的索引。然而,在图3中,当使用新创建的DWD_FDC_ALARM_HIST_0320
表替换原始的DWD_FDC_ALARM_HIST
表后,执行计划改变了,没有再使用索引。这可能是由于以下原因:
统计信息不一致:Oracle数据库依赖于表和索引的统计信息来做出优化决策。当创建新表DWD_FDC_ALARM_HIST_0320
时,它可能没有继承原表的统计信息,或者这些信息没有被更新。运行DBMS_STATS.GATHER_TABLE_STATS
对新表进行分析可能会解决这个问题。
执行计划的稳定性:Oracle的CBO(成本基优化器)可能会根据当前数据分布和负载选择不同的执行计划。即使两个表的数据完全相同,如果查询上下文稍有变化,CBO也可能选择不同的路径。
全表扫描更优:在某些情况下,尽管有索引,全表扫描可能更快,特别是当索引覆盖的数据比例小,且需要返回大量数据时。检查新表的大小和索引的利用率可能有助于确定这一点。
对于图4中的关联条件,优化可能包括:
避免在JOIN条件中使用函数:SUBSTR(t1.EQPID,1,7)
在JOIN条件中可能导致索引无法使用。如果可能,最好在JOIN条件中使用完整的字段,或者创建一个包含前7个字符的新索引。
考虑使用索引合并:如果有多个索引可以用于JOIN条件,Oracle的索引合并策略可能会更有效。确保所有相关字段都有适当的索引。
减少全表扫描:如果可能,尝试减少全表扫描,比如通过添加索引或者优化查询逻辑。
使用绑定变量:如果查询中的日期范围是动态的,使用绑定变量而不是硬编码日期可以帮助重用执行计划,从而提高性能。
查询优化:检查查询中的过滤条件,看看是否可以提前过滤数据,减少JOIN的数据量。
为了提供更具体的建议,我需要查看新的执行计划和相关的索引定义。如果可能,请提供新执行计划的详细信息以及DWD_FDC_ALARM_HIST_0320
表和ODS_FDC_EES_ANALYTICS_LINK
表的索引结构。此外,如果表中的数据量巨大,分析EXPLAIN PLAN
输出的cardinality
(基数)和bytes
(字节数)可能会提供更多信息。