PLOSCAR实现机制

本章节介绍了一些PLOSCAR的实现机制,用户在应用时可能会涉及到相关细节。

语句解析

在存储过程和函数里,SQL语句和表达式可以引用过程或函数里定义的参数和变量。

在这种情况下,PLOSCAR会使用参数和变量来替换这些引用。例如以下这个语句:

INSERT INTO foo (foo) VALUES (foo);

按照语法,在语句中,第一个foo是表名,不能被替换成参数或变量。第二个foo是列名,不能被替换。第三个foo是参数或者变量,需要被替换。

由于参数或变量的名字可以与表名、列名重名,在一些极端的情况下,参数和变量的替换会引起问题,例如:

INSERT INTO dest (col) SELECT foo + bar FROM src;

dest和src肯定是表名,col是列名,而foo和bar可能是变量,也可能是表中的列。这种情况下遇到变量名、参数名与列名重名冲突时,优先将符号解析为列名,对于不是列名的,才认为是变量或者参数。

PLOSCAR在语句解析时采取了如上策略,但是仍然建议用户在编写程序时,使用不同的变量名,避免发生歧义。

计划缓存

在循环体中出现的表达式,每一次执行都需要生成新的查询计划,执行之后查询计划将被释放,造成循环的执行效率低。由于缓存中没有将表达式和语句的查询计划保存起来,在每次执行都要生成计划,所以有性能上的损失。

因此PLOSCAR在循环里,无论查询计划是保存在表达式执行状态上还是保存在计划缓存里,计划都要重用,这样才能保证循环的高效执行。

要使用计划缓存,需要开启配置参数ENABLE_PL_PLANCACHE,并调用alter procedure/function … compile编译函数后才能使用计划缓存,失效后需要进行重新编译。

在计划缓存中保存计划能带来的好处:

  1. 由于查询计划已经提前生成好了,PLOSCAR的执行效率能得到提高。首次执行会产生计划,以后的执行将不再生成计划(计划不能重用的除外),能省去了一些计划生成的时间。
  2. 当PLOSCAR并发执行或者递归调用时,所用到的查询计划都来自于计划缓存,内存里不会保存重复的计划。

在PLOSCAR中保存计划可能引发的问题:

  1. 计划失效时,需要对计划缓存进行更新,但当前没有自动更新的方法。
  2. 所执行的查询计划在最开始生成,之后数据发生变化后,之前的计划可能不是最优的。