标签:time 预测 end 进入 sql语句 硬件 运行时间 共享 个数
本文参考了https://blog.csdn.net/xinzhan0/article/details/52461611?locationNum=2&fps=1
如何设置shared pool及sga的大小
前面讲了很多关于shared pool的知识
对我们来讲最简单最直接的工作是
sharedpool到底该设多大
一)shared pool大的坏处
有人说数据库所在的服务器物理内存很大
可以把sharedpool设的很大
理论上讲一个数据库所要执行的sql语句是无限的
这样就需要一个无限的shared_pool去存储sql语句和它的执行计划
而我们使用的内存总是有限的
从这方面讲其值设的再大也会出现4031错误
另一方面sharedpool设大了也有坏处
分析一下
1、第一种坏处
sharedpool里面有free空间、librarycache和rowcache
数据库运行时有时硬解析非常多
硬解析多意味着
sql语句来了,我拿着sql语句到librarycache去找又没有找着
没有找着就解析
解析完了以后还需要到free里面找空的chunk把解析的结果写进去
再把它挂到librarycache上
整个过程非常复杂
第一要找
第二要找空的
第三把解析后的内容写到空的上,再把空的挂到librarycache上
然后执行下一个sql
因为sql共享做的不好
带来一个问题
刚才复杂的花了很长时间
把这个sql挂到了写到了librarycache上
因为共享做的不好后面没有被使用
后面每条sql语句都是硬解析
每条sql语句都重复着刚才讲的故事
找、去解析、找空的、挂过去
如果说反过来讲
现在一条sql语句来了
不去librarycache里面找
sql语句解析完了也不去缓存
sql语句来了直接硬解析
解析完了执行
执行完了把解析结果就扔了
这样的话比刚才的步骤还简单
结论:
如果sql语句没有共享
大量的硬解析时sharedpool的作用是反的
在这种情况下
如果我把sharedpool设的很大
在没有实现共享sql的前提下
oracle的硬解析会非常的多
而硬解析的每一步都要执行
即使很多步骤对执行一条命令获得结果并没有作用
这个时候有sharedpool不如没有sharedpool,它浪费了太多资源
当然oracle不可能没有sharedpool我们只是这么说
2、第二种坏处
如果我把sharedpool设的很大
librarycache里面就会很大
sharedpool设的很大,大量的sql就会被缓存到librarycache里面
也就是librarycache里面的链会非常的长
链长的话一个sql语句来了
如果共享的话它应该挂在第一个链上
假设第一个链上有500个chunk
如果sharedpool小的话只能够搁100个chunk
但是我们这里放了500个chunk
这个sql语句就在这个链上一个一个比较到底一不一样
因为不一样
所以这个sql语句要比较500个chunk
在比较这500个chunk的时候
因为正在访问这个链要把这个链锁住
再回顾一下
因为sharedpool设的很大,自然librarycache就大
自然librarycache上挂的chunk就多
这个时候一个sql语句在一个链上找一个chunk的时候
因为它是硬解析它在这个链上肯定没有
它就会把500个都比较完
就会长时间的锁住这个链
它锁住这个链
另外一个sql也同样找链的时候
会发生链的争用 锁的争用
总结:
shared_pool大了链就会很长
自己遍历链花很长时间
而且和别的sql可能会发生链的争用使其它sql等待很长时间
危害就更大
二)给shared pool选择合适的大小值
1)给shared pool单独选择合适的大小值
所以说在oracle以前老的版本里面
在oracle10以前
sharedpool我们建议不要超过一个G
超过一个G可能会带来反作用
从oracle10G开始
可以设置超过1G
如:2G、5G
老师看过一个生产系统上
一个sharedpool设了10G
可以设的大一些
因为在oracle10G里面
它用了这么一个技术
它把一个大的sharedpool设成很多子的sharedpool
也就是设成了多个小的sharedpool
每个小的sharedpool里
都有自己的一些链
它保证这些链不会太长
但是我们也不要设太大
手工设sharedpool时如何选择大小
查看当前系统shared pool 大小:
select component, current_size,min_size,max_size,user_specified_size from v$sga_dynamic_components;
show parameter shared_pool_size ;查看可能是0,当状态是不对的,因为11g是自动管理的。
oralce有相关的语句可以执行:
SELECT ‘Shared Pool‘ component,shared_pool_size_for_estimate estd_sp_size,
estd_lc_time_saved_factor parse_time_factor,
case
WHEN current_parse_time_elapsed_s + adjustment_s < 0
THEN 0 ELSE current_parse_time_elapsed_s + adjustment_s
END response_time FROM (SELECT shared_pool_size_for_estimate,shared_pool_size_factor,
estd_lc_time_saved_factor,a.estd_lc_time_saved,
e.VALUE/100 current_parse_time_elapsed_s,
c.estd_lc_time_saved - a.estd_lc_time_saved adjustment_s FROM v$shared_pool_advice a,
(SELECT * FROM v$sysstat WHERE NAME = ‘parse time elapsed‘) e,
(SELECT estd_lc_time_saved FROM v$shared_pool_advice WHERE shared_pool_size_factor = 1) c);
COMPONENT ESTD_SP_SIZE PARSE_TIME_FACTOR RESPONSE_TIME
----------- ------------ ----------------- -------------
Shared Pool 64 .9871 23.3
Shared Pool 76 .9943 18.3
Shared Pool 88 .9986 15.3
Shared Pool 100 1 14.3
Shared Pool 112 1 14.3
Shared Pool 124 1 14.3
Shared Pool 136 1 14.3
Shared Pool 148 1 14.3
Shared Pool 160 1 14.3
Shared Pool 172 1 14.3
Shared Pool 184 1 14.3
Shared Pool 196 1 14.3
Shared Pool 208 1 14.3
13 rows selected.
结果中
COMPONENT(组件)列为shared Pool
ESTD_SP_SIZE列
为假设shared Pool的大小值
RESPONSE_TIME列
为sql语句反应时间
是预测到的一个sql语句解析花费的平均时间
shared pool设的值不同,预测花费的时间可能会有改变
结果中 shared pool为64M 一个sql语句解析花费的时间为23.3
为76M 响应时间为18.3
为88M 响应时间为15.3
为100M 响应时间为14.3
总体随着预设的ESTD_SP_SIZE值的增加
相应的响应时间在减少
这是好事
但是ESTD_SP_SIZE增加到一定程度以后
上例为
Shared Pool 100 1 14.3
Shared Pool 112 1 14.3
随着空间的增加
RESPONSE_TIME的数值就不变了
这样shared pool设到
RESPONSE_TIME值稳定后的第一个值就可以了
这里是100M
在我的软硬件环境设为100M就可以了。
我的实验系统使用的虚拟机没有负载反应的不太真实
而且从实践中可以看到
从数据库刚启动开始
随着oracle数据库运行时间的增加
预测得到的最佳sharedpool的大小值会一步步增加。
因为随着运行时间增长数据库负载会增大
相同sharedpool大小造成的响应时间会变长,
而且最佳大小的值也在增大。
就是这个预测值是在变化的。
实际通过这个sql语句取出相关的值以后
一般的取
PARSE_TIME_FACTOR
的值从1开始(后面的值一般都是1)对应的ESTD_SP_SIZE数据
就是我们应该设的
这是sharedpool单独设的方法
2)给sga选择合适的大小值
如果没有手工设sharedpool
sharedpool纯粹的用sga_target自动设置
我们判断sga_target到底多大就可以了
其实可以在em里面查询设置sga
首先启动em
使用ie浏览器,我的本机网址
http://192.168.3.47:1158/em
以SYSDBA身份登录
在首页 相关链接 中找到
指导中心
在指导中心页找到
指导 内存指导
进入 内存参数 页
在SGA标签页
在 当前分配 中有
SGA总大小(MB)
我的值是 272
点后面的建议按钮,打开 SGA大小建议 图表
当SGA的值超过一定点的时候
SGA总大小(MB) 改变 数据库时间的改善百分比 就不变了
对数据库影响就不大了
SGA实际大小在这个图表中调整也可以
如果空间足够的话,可以设的稍微大一些
这个地方讲的是我们如何去设置sharedpool的大小
有两种预测选择大小值的方法
一个是使用em一个直接使用sql语句查
在Oracle10g中允许有多个sub shared pool,可以设置大于1G的shared pool
oracle10G以前都小于1G
oracle10G以后都大于1G
尽量不要太大
三)执行计划
sga的sharedpool里面librarycache里面缓存的是执行计划
我们可以看一下执行计划
可以使用查询语句
select * from table(dbms_xplan.display_cursor(‘g4pkmrqrgxg3b‘));
查到执行计划
其中g4pkmrqrgxg3b是sqlID,不同的sql语句ID不同
把sqlID找出以后把它覆盖就可以执行了
假设去执行一个语句并找到它的执行计划
SQL> alter system flush shared_pool;
System altered.
先清了shared_pool,
这个语句的执行,是为了使举例语句每次运行的环境基本相同
这样生成的执行计划也基本是相同的
可能这个语句太简单
比较老师机子生成的执行计划
和我的机子生成的执行计划只有个别地方有微小的区别。
执行计划是为了使语句执行过程最优化
它的生成要根据软硬件环境由oracle去选择最优的方案
所以有些oracle所在内外部环境的变化可以使生成的计划发生变化
如要检索的表是否使用索引会造成生成的执行计划不同。
执行一下要查看它的执行计划的语句
SQL> select count(*) from dba_objects;
COUNT(*)
----------
50361
执行了以后这个sql语句的执行计划应该在librarycache里面出现了
现在看看执行计划是什么
首先找sql语句对应的sqlID
SQL> select sql_id,sql_text from v$sql where sql_text like ‘%count(*) from dba_objects%‘;
SQL_ID
-------------
SQL_TEXT
----------------------------------------------------------------------------------------------------
g4pkmrqrgxg3b
select count(*) from dba_objects
发现对应的sqlID是g4pkmrqrgxg3b
然后使用
select * from table(dbms_xplan.display_cursor(‘g4pkmrqrgxg3b‘));
查看执行计划
这条语句的结果较长
可以将sql命令行输出的行宽和页长改大以使结果显示的有条理
可以设置linesize、pagesize的大小
SQL> set linesize 100
设置显示结果中每行的长度
SQL> set pagesize 1000
设置显示结果每页多少行
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SQL> select * from table(dbms_xplan.display_cursor(‘g4pkmrqrgxg3b‘));
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
SQL_ID g4pkmrqrgxg3b, child number 0
-------------------------------------
select count(*) from dba_objects
Plan hash value: 2598313856
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 144 (100)| |
| 1 | SORT AGGREGATE | | 1 | | | |
| 2 | VIEW | DBA_OBJECTS | 48840 | | 144 (5)| 00:00:02 |
| 3 | UNION-ALL | | | | | |
|* 4 | FILTER | | | | | |
|* 5 | HASH JOIN | | 51423 | 4117K| 143 (5)| 00:00:02 |
| 6 | TABLE ACCESS FULL | USER$ | 62 | 186 | 2 (0)| 00:00:01 |
|* 7 | TABLE ACCESS FULL | OBJ$ | 51423 | 3967K| 140 (4)| 00:00:02 |
|* 8 | TABLE ACCESS BY INDEX ROWID| IND$ | 1 | 8 | 2 (0)| 00:00:01 |
|* 9 | INDEX UNIQUE SCAN | I_IND1 | 1 | | 1 (0)| 00:00:01 |
| 10 | NESTED LOOPS | | 1 | 16 | 1 (0)| 00:00:01 |
| 11 | INDEX FULL SCAN | I_LINK1 | 1 | 13 | 0 (0)| |
| 12 | TABLE ACCESS CLUSTER | USER$ | 1 | 3 | 1 (0)| 00:00:01 |
|* 13 | INDEX UNIQUE SCAN | I_USER# | 1 | | 0 (0)| |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter((("O"."TYPE#"<>1 AND "O"."TYPE#"<>10) OR ("O"."TYPE#"=1 AND =1)))
5 - access("O"."OWNER#"="U"."USER#")
7 - filter(("O"."NAME"<>‘_NEXT_OBJECT‘ AND "O"."NAME"<>‘_default_auditing_options_‘
AND "O"."LINKNAME" IS NULL))
8 - filter(("I"."TYPE#"=1 OR "I"."TYPE#"=2 OR "I"."TYPE#"=3 OR "I"."TYPE#"=4 OR
"I"."TYPE#"=6 OR "I"."TYPE#"=7 OR "I"."TYPE#"=9))
9 - access("I"."OBJ#"=:B1)
13 - access("L"."OWNER#"="U"."USER#")
37 rows selected.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
这样的结果很清晰
可看出结果是关于sql语句
select count(*) from dba_objects
对应的一个执行计划
只有读懂执行计划
你才能知道执行计划好不好
到目前为止,我们相对深入的讲了oracle的sharedpool
里面内容比较多也比较杂乱一些
没有一个很好的思路去讲这个东西
很多知识是中间插进来的
大家以后把视频多看几遍慢慢就掌握了
————————————————
版权声明:本文为CSDN博主「新站」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xinzhan0/article/details/52461611
标签:time 预测 end 进入 sql语句 硬件 运行时间 共享 个数
原文地址:https://www.cnblogs.com/magic-dw/p/14603920.html