引言

在大型的企业级应用中,数据库查询操作是经常使用的重要环节。然而,当查询语句中存在绑定变量时,不同的绑定变量值可能导致执行计划的不一致,从而影响查询性能。为了解决这个问题,Oracle数据库引入了自适应游标共享(Adaptive Cursor Sharing,ACS)的技术,它能够自动调整执行计划,提高查询性能。本文将深入探讨Oracle自适应游标共享的原理和优势。

简介

Oracle在11g中引入了自适应游标共享(Adaptive CursorSharing)。自适应游标共享可以在启用了绑定变量窥探的前提条件下,让目标SQL在其可能的多个执行计划之间“自适应”地做出选择,而不再像之前那样必须得刻板地沿用该SQL硬解析时所产生的解析树和执行计划。

那么什么叫“自适应”呢?Oracle会根据执行目标SQL时所对应的runtime统计信息(比如所耗费的逻辑读和CPU时间,对应结果集的行数等)的变化,以及当前传入的绑定变量输入值所在的谓词条件的可选择率,来综合判断是否需要触发目标SQL的硬解析动作。

原理

  1. 标记Bind Sensitive

    所谓“Bind Sensitive”,就是指Oracle觉得某个含绑定变量的目标SQL的执行计划可能会随着所传入的绑定变量输入值的变化而变化。
    当满足如下三个条件时,目标SQL所对应的Child Cursor就会被Oracle标记为Bind Sensitive。

    • 启用了绑定变量窥探。
    • 该SQL使用了绑定变量(不管是该SQL自带的绑定变量,还是开启常规游标共享后系统产生的绑定变量)。
    • 该SQL使用的是不安全的谓词条件(例如范围查询,目标列上有直方图统计信息的等值查询等)。
  2. 标记Bind Aware

    所谓“Bind Aware”,就是指Oracle已经确定某个含绑定变量的目标SQL的执行计划会随着所传入的绑定变量输入值的变化而变化。
    当满足如下两个条件时,目标SQL所对应的Child Cursor就会被Oracle标记为Bind Aware。

    • 该SQL所对应的Child Cursor在之前已经被标记为Bind Sensitive。
    • 该SQL在接下来连续两次执行时,所对应的runtime统计信息与该SQL之前硬解析时所对应的runtime统计信息存在较大差异

V$SQL中的列IS_BIND_SENSITIVE、IS_BIND_AWARE和IS_SHAREABLE分别用来表示Child Cursor是否是Bind Sensitive、Bind Aware和共享的。
V$SQL_CS_STATISTICS用于显示指定Child Cursor中存储的runtime统计信息。
V$SQL_CS_SELECTIVITY用于显示指定的、已经被标记为Bind Aware的Child Cursor中存储的含绑定变量的谓词条件所对应的可选择率的范围。

实践

优势和特点

自适应游标共享技术带来了以下几个重要优势:

改善查询性能

自适应游标共享可以根据实际的绑定变量值自动选择最佳的执行计划,避免了由于绑定变量值的不同而导致的查询性能问题。无论是高选择性的绑定变量值还是低选择性的绑定变量值,都能够得到一个合适的执行计划,从而提高查询性能。

节省资源

传统的解决方案是为每个不同的绑定变量值生成一个独立的执行计划,导致执行计划的数量庞大,占用大量的内存和CPU资源。而自适应游标共享通过自动调整执行计划,可以避免生成过多的执行计划,从而节省系统资源。

自适应性和灵活性

自适应游标共享技术具有自动检测和适应环境变化的能力。如果环境发生变化,比如某个绑定变量值的分布情况发生变化,Oracle可以根据新的执行情况来自动调整执行计划,以适应新的环境,保持查询性能的稳定性和一致性。

实际应用

自适应游标共享技术在实际应用中具有广泛的应用场景,特别是在复杂的查询环境中更加显著。它可以解决由于绑定变量值的不同而导致的查询性能问题,提高系统的稳定性和可用性。同时,它还可以减少对DBA的依赖,降低了开发和维护的成本。