zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

【SQL 调优】绑定变量窥测

SQL变量 绑定 调优
2023-09-14 08:57:16 时间

绑定变量窥测:在物理优化阶段,查询优化器会窥测绑定变量的值,将它作为文本来使用。这种方法的问题是它生成的执行计划会依赖第一次生成执行计划时所提供的值。
--建立索引                                                                          
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
已用时间:  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
已用时间:  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)


sql调优之:字符集不一致导致的索引失效案例 生产上有一段sql,大概几百行,做的是inser into …select ;的操作,但是执行了一个多小时都出不来,正常情况下不会这么久,通过一步步定位,最后发现是其中某一段的join 特别慢导致的,后面对这段sql重点分析发现,这里的表竟然没有走索引,对于几十万以上的表之间的连接,若是没有索引那就是灾难性的,加不加索引就好比一个人力三轮与超跑的区别。
【笔记】SQL调优指南—调优方法论 找出需调优的慢SQL后,先通过EXPLAIN查看执行计划,然后通过如下方法优化SQL:下推更多计算至存储层MySQL,适当增加索引,优化执行计划。
SQL调优指南—智能索引推荐 索引优化通常需要依赖运维或开发人员对数据库引擎内部优化和执行原理的深入理解。为优化体验和降低操作门槛,PolarDB-X推出了基于代价优化器的索引推荐功能,可根据查询语句分析并推荐索引,帮助您降低查询耗时,提升数据库性能。
PostgreSQL native partition 分区表性能优化之 - 动态SQL+服务端绑定变量 PostgreSQL , 分区表 , native partition , 性能 , pg_pathman , plpgsql , 动态SQL , 服务端绑定变量 , prepare , execute 目前PG的native partition分区性能不佳,一种解决方法是使用pg_pathman插件,另一种方法是业务上直接插分区,还有一种方法是使用UDF函数接口(函数内部使
[20180301]sql profile 非绑定变量.txt [20180301]sql profile 非绑定变量.txt http://www.itpub.net/thread-2097379-1-1.html 1.环境: SCOTT@book @ r/ver1 PORT_STRING ...