【SQL 调优】绑定变量窥测

简介:

绑定变量窥测:在物理优化阶段,查询优化器会窥测绑定变量的值,将它作为文本来使用。这种方法的问题是它生成的执行计划会依赖第一次生成执行计划时所提供的值。
--建立索引                                                                          
SQL> create index i_obj_id on t_var_peek(object_id);

索引已创建。

已用时间:  00: 00: 00.25
---执行计划选择了 range scan
SQL> select count(object_id) from t_var_peek where object_id < 10;
已用时间:  00: 00: 00.01
执行计划
----------------------------------------------------------                                                       
Plan hash value: 1952566611                                                                                             

------------------------------------------------------------------------------    
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |        
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |          |     1 |    13 |     2   (0)| 00:00:01|                
|   1 |  SORT AGGREGATE   |          |     1 |    13 |            |         |                                          
|*  2 |   INDEX RANGE SCAN| I_OBJ_ID |     8 |   104 |     2   (0)| 00:00:01|                                   
 ------------------------------------------------------------------------------                                         

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("OBJECT_ID"<10)       
Note                                     
   - dynamic sampling used for this statement   
----使用绑定变量      
SQL> exec :x1 :=999;
PL/SQL 过程已成功完成。
已用时间:  00: 00: 00.01
SQL> select count(object_id) from t_var_peek where object_id < :x1;
已用时间:  00: 00: 00.00
执行计划
----------------------------------------------------------
 Plan hash value: 1952566611  
------------------------------------------------------------------------------                                        

| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |   
------------------------------------------------------------------------------   
|   0 | SELECT STATEMENT  |          |     1 |    13 |     3   (0)| 00:00:01 | 
|   1 |  SORT AGGREGATE   |          |     1 |    13 |            |          |
|*  2 |   INDEX RANGE SCAN| I_OBJ_ID |  3439 | 44707 |     3   (0)| 00:00:01 |
  ------------------------------------------------------------------------------
Predicate Information (identified by operation id):
  ---------------------------------------------------  
   2 - access("OBJECT_ID" Note   
   -----  
   - dynamic sampling used for this statement                                                                         (:x1))

----此时 返回的行数和cost 大小是和 :X1=999 的值是一样的。说明第一次优化是使用值999来执行的。结果,查询优化器就选择了INDEX RANGE SCAN。由于游标是共享的,因此是这个选择影响了第二次使用9作为条件的查询语句。
SQL> exec :x1 :=9;
PL/SQL 过程已成功完成。
已用时间:  00: 00: 00.01
SQL> select count(object_id) from t_var_peek where object_id < :x1;
已用时间:  00: 00: 00.00
执行计划
----------------------------------------------------------  
Plan hash value: 1952566611  
------------------------------------------------------------------------------                                          

 | Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |                                         
------------------------------------------------------------------------------                                          
|   0 | SELECT STATEMENT  |          |     1 |    13 |     3   (0)| 00:00:01 |                                         

|   1 |  SORT AGGREGATE   |          |     1 |    13 |            |          |                                         

|*  2 |   INDEX RANGE SCAN| I_OBJ_ID |  3439 | 44707 |     3   (0)| 00:00:01 |                                          

  ------------------------------------------------------------------------------     
 Predicate Information (identified by operation id):        
--------------------------------------------------- 
   2 - access("OBJECT_ID" Note       
-----    
   - dynamic sampling used for this statement 
---在使用 <9 时 请注意执行计划的rows 和 bytes cost的值!
SQL> select count(object_id) from t_var_peek where object_id < 9;
已用时间:  00: 00: 00.01(:x1))    >

执行计划
----------------------------------------------------------       
Plan hash value: 1952566611  
------------------------------------------------------------------------------                                          
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |       
------------------------------------------------------------------------------       
|   0 | SELECT STATEMENT  |          |     1 |    13 |     2   (0)| 00:00:01 |       
|   1 |  SORT AGGREGATE   |          |     1 |    13 |            |          |        
|*  2 |   INDEX RANGE SCAN| I_OBJ_ID |     7 |    91 |     2   (0)| 00:00:01 |                                          

  -----------------------------------------------------------------------------     
    Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("OBJECT_ID"<9)
Note
-----
   - dynamic sampling used for this statement   
--此时:x1 的值还是 9 但是执行计划的和前面 :X1 =999 和 :X1=999 的执行计划是一样的,明显的发生了变量窥测!  
SQL> select count(object_id) from t_var_peek where object_id < :x1;
已用时间:  00: 00: 00.00
执行计划
---------------------------------------------------------- 
Plan hash value: 1952566611
------------------------------------------------------------------------------       
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |      
------------------------------------------------------------------------------                                         
|   0 | SELECT STATEMENT  |          |     1 |    13 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE   |          |     1 |    13 |            |          |     
|*  2 |   INDEX RANGE SCAN| I_OBJ_ID |  3439 | 44707 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------                                           

     Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("OBJECT_ID" Note
-----
   - dynamic sampling used for this statement
   只要游标还保存在库缓存中并且可以被共享,就可以被重用。不管与它相关的执行计划的效率如何,这种事情都会发生。         
解决办法:
   为了解决这个问题,Oracle11g中引入了一个称为扩展的游标共享(extended cursor sharing,也称为适应性游标共享,adaptive cursor sharing)的新功能。它的目的是在重用一个已经存在的但是会导致执行效率低下的游标时能够自动进行识别。(:x1)

相关文章
|
8月前
|
SQL 数据库 开发者
MSSQL性能调优实战技巧:索引优化、SQL语句微调与并发控制策略
在Microsoft SQL Server(MSSQL)的管理与优化中,性能调优是一项复杂但至关重要的任务
|
8月前
|
SQL 监控 数据库
MSSQL性能调优实战策略:索引优化、SQL语句重构与并发控制
在Microsoft SQL Server(MSSQL)的管理和优化过程中,性能调优是确保数据库高效运行、满足业务需求的重要环节
|
8月前
|
SQL 运维 监控
MSSQL性能调优实战:索引优化、SQL查询效率提升与并发控制策略
在Microsoft SQL Server(MSSQL)的日常运维与性能优化中,精准的策略与技巧是实现高效数据库管理的关键
|
8月前
|
SQL 存储 数据库
MSSQL性能调优实战:索引优化、SQL语句精调与高效并发处理
在Microsoft SQL Server(MSSQL)的性能调优征途中,索引优化、SQL语句的精细调整以及高效并发处理是三大核心策略
|
8月前
|
SQL 监控 数据库
MSSQL性能调优实战技巧:索引优化策略、SQL查询重构与并发控制详解
在Microsoft SQL Server(MSSQL)的管理与优化过程中,性能调优是确保数据库高效运行的关键环节
|
8月前
|
SQL 运维 监控
MSSQL性能调优实战:索引深度优化、SQL查询技巧与高效并发控制
在Microsoft SQL Server(MSSQL)的运维环境中,性能调优是确保数据库高效、稳定运行的核心任务
|
8月前
|
SQL 监控 数据库
MSSQL性能调优实战指南:精准索引策略、SQL查询优化与高效并发控制
在Microsoft SQL Server(MSSQL)的性能调优过程中,精准索引策略、SQL查询优化以及高效并发控制是三大核心要素
|
6月前
|
存储 SQL 关系型数据库
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
MySQL调优主要分为三个步骤:监控报警、排查慢SQL、MySQL调优。 排查慢SQL:开启慢查询日志 、找出最慢的几条SQL、分析查询计划 。 MySQL调优: 基础优化:缓存优化、硬件优化、参数优化、定期清理垃圾、使用合适的存储引擎、读写分离、分库分表; 表设计优化:数据类型优化、冷热数据分表等。 索引优化:考虑索引失效的11个场景、遵循索引设计原则、连接查询优化、排序优化、深分页查询优化、覆盖索引、索引下推、用普通索引等。 SQL优化。
891 15
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
|
5月前
|
SQL Oracle 关系型数据库
Oracle SQL:了解执行计划和性能调优
Oracle SQL:了解执行计划和性能调优
133 1
|
6月前
|
SQL 分布式计算 数据库
SQL调优总结
数据库表的规范化和反规范化设计,设计合适的字段数据类型……
59 8

热门文章

最新文章