Adapting and adopting SQL Plan Management (SPM)
Introduction
This post is about: “Adapting and adopting SQL Plan Management (SPM) to achieve execution plan stability for sub-second queries on a high-rate OLTP mission-critical application”. In our case, such an application is implemented on top of several Oracle 12c multi tenant databases, where a consistent average execution time is more valuable than flexible execution plans. We successfully achieved plan stability implementing a simple algorithm using PL/SQL calling DBMS_SPM public APIs.
Chart below depicts a typical case where the average performance of a large set of business-critical SQL statements suddenly degraded from sub-millisecond to 15 or 20ms, then beccome more stable around 3ms. Wide spikes are a typical trademark of an Execution Plan for one or more SQL statements flipping for some time. In order to produce a more consistent latency we needed to improve plan stability, and of course the preferred tool to achieve that on an Oracle database is SQL Plan Management.
Algorithm
We tested and ruled out adaptive SQL Plan Management, which is an excellent 12c new feature. But, due to the dynamics of this application, where transactional data shifts so fast, allowing this “adaptive SPM” feature to evaluate auto-captured plans using bind variable values captured a few hours earlier, rendered unfortunately false positives. These false positives “evolved” as execution plans that were numerically optimal for values captured (at the time the candidate plan was captured), but performed poorly when executed on “current” values a few hours later. Nevertheless, this 12c “adaptive SPM” new feature is worth exploring for other applications.
We adapted SPM so it would only generate SQL Plan Baselines on SQL that executes often, and that is critical for the business. The algorithm has some complexity such as candidate evaluation and SQL categorization; and besides SPB creation it also includes plan demotion and plan promotion. We have successfully implemented it in some PDBs and we are currently doing a rollout to entire CDBs. The algorithm is depicted on diagram on the left, and more details are included in corresponding presentation slides listed on the right-hand bar. I plan to talk about this topic on an international Oracle Users Group in 2018.
This algorithm is scripted into a sample PL/SQL package, which you can find on a subdirectory on my shared scripts. If you consider using this sample script for an application of your own, be sure you make it yours before attempting to use it. In other words: fully understand it first, then proceed to customize it accordingly and test it thoroughly.
Results
Chart below shows how average performance of business-critical SQL became more stable after implementing algorithm to adapt and adopt SPM on a pilot PDB. Not all went fine although: we had some outliers that required some tuning to the algorithm. Among challenges we faced: volatile data (creating a SPB when table was almost empty, then using it when table was larger); skewed values (create a SPB for non-popular value, then using it on a popular value); proper use of multiple optimal plans due to Adaptive Cursor Sharing (ACS); rejected candidates due to conservative initial restrictions on algorithm (performance per execution, number of executions, age of cursor, etc.)
Conclusion
If your OLTP application contains business critical SQL that executes at a high-rate, and where a spike on latency risks affecting SLAs, you may want to consider implementing SQL Plan Management. Consider then both: “adaptive SPM” if it satisfies your requirements, else build a PL/SQL library that can implement more complex logic for candidates evaluation and for SPBs maintenance. I do believe SPM works great, specially when you enhance its out-of-the-box functionality to satisfy your specific needs.
Hi Carlos,
thanks for Your blog. What script would You recommend in order to fix sql plan from one sql_id to different sql_id as baseline or sql_profile ? Those sql_id differs because of some comments added by app layer and bind variables .
Regards .
Grzegorz
Grzegorz Goryszewski
January 14, 2018 at 1:09 am
I suggest you try coe_xfr_sql_profile.sql
Carlos Sierra
January 15, 2018 at 6:32 pm
Awesome work man do check out my blog https://www.varunsood.com/sql-query-for-getting-age-in-years/
Varun Sood
February 12, 2018 at 1:58 am
Hi Carlos – the subdirectory path to PL/SQL package (https://github.com/carlos-sierra/cscripts/tree/master/sql/iod_spm_fpz) doesn’t work. Where I could download it from?
Nikolay
February 19, 2021 at 3:29 am
I will send it to you by email
Carlos Sierra
February 19, 2021 at 8:13 am
Hi .Carlos .. as usual awesome blog/info. I also can’t access https://github.com/carlos-sierra/cscripts/tree/master/sql/iod_spm_fpz location.. Can you please help? Thanks, Pushkar
Pushkar
May 17, 2021 at 2:08 pm
Thanks Carlos for continued work in Oracle world! I also can’t the shared location https://github.com/carlos-sierra/cscripts/tree/master/sql/iod_spm_fpz .. Can you please help?
pupakare
May 17, 2021 at 2:10 pm
Shared scripts are now under “free downloads”. If you don’t find a specific script or tool there, please email me
Carlos Sierra
May 18, 2021 at 6:31 am
Hello Carlos,
The charts you present from what queries are they made of, which query you use?
Regards,
Mike
Mike
July 19, 2022 at 7:09 am
They come from the cs scripts
Carlos Sierra
July 19, 2022 at 9:14 am