自适应游标共享如何工作
两个概念--游标的绑定敏感性和确认绑定的游标(bind-aware cursor)—在自适应游标共享如何工作中起关键的作用。如果更改一个绑定变量的值导致不同的执行计划,则游标称为绑定敏感的游标(bind-sensitive cursor)。当数据库认为由于绑定值变化很大,它必须创建新执行计划时,则变量确实是绑定敏感的。数据库标记某个游标为绑定敏感变量后,该游标就称为确认绑定(bind aware)游标。
注解 自适应游标共享特性不依赖于游标共享特性。
下面举一个例子,说明自适应游标共享如何工作。假定你在数据库中执行几次下面的査询:
select * from hr.employees where salary = :1 and departmcnt_id = :2;
此SQL语句使用两个绑定变量SALARY和DEPARTMENT_ID.
在新SQL语句第一次执行中,如果数据库窥视到痴定变量并且计算了相应谓词的选择性,则它使游标具备绑定敏感性。数据库赋予每个执行计划一组选择性值,如(0.25,0.0050),它表示执行计划的选择性范围。如果新绑定变量落在这个选择性范围内,则优化程序重用相应的执行计划,如果不落在这个范围,它创建一个新的执行计划。
下一步是估计游标是否为一个确认绑定的游标。在首次硬分析后,数据库对后续的执行进行软分析,并且比较执行统计数据与硬分析执行统计数据。如果数据库确定游标是确认绑定的,则在它再次执行査询时使用确认绑定的游标匹配。
如果新绑定值对落在相应的选择性范围内,数据库重用该计划;否则,进行一个硬分析,从而生成一个具有不同计划的新的子游标。如果新执行生成类似的计划,则数据库合并子游标,这表示如果绑定值大致相同,各语句将共享执行计划。
监控自适应游标共享
V$SQL视图含有两列,名为IS_BIND_SENSITIVE和IS_BIND_AWARE,帮助监控数据库中的自适应游标共享.IS_BIND_SENSITIVE列让你知道一个游标是否是绑定敏感的,IS_BIND_AWARE列显示数据库是否已经为知道绑定的游标共享标记了一个游标。例如,以下査询告诉你哪些SQL语句是绑定敏感的,哪些是确认绑定的:
SELECT sql_id, executions, is_bind_sensitive, is_bind_aware FROM v$sql;
在此查询中,IS_BIND_SENSITIVE列显示数据库是否将根据绑定变量值生成不同的执行计划。显示IS_BIND_SENSITIVE列值糸Y的任意游标都是当执行计划更改的候选计划。当数据库根据观察到的绑定变原的瓦打算使用一条语句的多个执行计划时,它对该语句标记IS_BIND_AWARE列为Y。
这表示优化程序认识到,不同的绑定变量值将导致不同的数据模式,这要求下一汲执行时对语句进行硬分析。为了决定是否更改执行计划,数据库要估计SQL语句的下几次执行计划。如果数据库确定要更改一条语句的执行计划,它将标记游标为确认绑定的,并设置该语句的IS_BIND_AWARE列值为Y。确认绑定的游标是数据库己经根据观察到的绑定变量的值实际修改了执行计划的游标。
可利用以下视图管理自适应游标共享特性:
- v$sql_cs_histogram:显示执行历史直方图上的执行计数的分布;
- v$sql_cs_selectivity:显示存储在具有绑定变量的谓词的游标中的选择性范围;
- v$sql_cs_statistics:包含数据库收集的使用不同绑定集的游标的执行统计数据。
1.定期对表和索引进行重建
在一个具有大量DML操作的数据库中,索引会变得不平衡。定期对索引进行重建是很重要的,这可以让査询运行的更快。你必须重建索引以改变其存储特性或者强化索引并减少碎片。使用ALTER INDEX...REBUILD语句,旧的索引在对索引进行重建过程中仍然可以被访问(可选的方法是删除索引然后再重新创建它)。
由于在重建索引时包含了COMPUTE STATISTICS语句,因此你不能在重建后搜集统计数据。当然,如果你的环境是24/7的,可以使用ALTER INDEX.. .REBUILD ONLINE语句,这样用户对数据库的访问就不会受影响。在进行联机索引重建时,不能对表进行大量的DML操作,这一点很重要。因为在这种环境下,联机特性可能不像广告所介绍的那样工作。它甚至最终可能会出乎意料地阻止用户的同步更新。
2.回收不使用的空间
Segment Advisor会在定期安排的每晚的维护中自动运行,并提供关于你可以收缩的对象的建议,目的是收回浪费的空间。要记住的是,为了使用Segment Advisor,你需要使用具有自动段空间管理的本地管理的表空间。收缩段能节省空间,但更重要的是,通过降低段的高水位标记,消除具有大量更新和删除操作的对象中随时间流逝不可避免地产生的碎片,可以改进性能。
3.在内存中高速缓存较小的表
如果应用在很长的一段时间内都没有重用一个&的数据,这些数据可能会在SGA中过期,需要重新从磁盘中读取。可以像卜面这样将一个较小的表中的数据安全地存放在缓冲区高速缓存中:
ALTER TABLE hr.employees CACHE;