- 浏览: 7955822 次
- 性别:
- 来自: 广州
-
文章分类
- 全部博客 (2425)
- 软件工程 (75)
- JAVA相关 (662)
- ajax/web相关 (351)
- 数据库相关/oracle (218)
- PHP (147)
- UNIX/LINUX/FREEBSD/solaris (118)
- 音乐探讨 (1)
- 闲话 (11)
- 网络安全等 (21)
- .NET (153)
- ROR和GOG (10)
- [网站分类]4.其他技术区 (181)
- 算法等 (7)
- [随笔分类]SOA (8)
- 收藏区 (71)
- 金融证券 (4)
- [网站分类]5.企业信息化 (3)
- c&c++学习 (1)
- 读书区 (11)
- 其它 (10)
- 收藏夹 (1)
- 设计模式 (1)
- FLEX (14)
- Android (98)
- 软件工程心理学系列 (4)
- HTML5 (6)
- C/C++ (0)
- 数据结构 (0)
- 书评 (3)
- python (17)
- NOSQL (10)
- MYSQL (85)
- java之各类测试 (18)
- nodejs (1)
- JAVA (1)
- neo4j (3)
- VUE (4)
- docker相关 (1)
最新评论
-
xiaobadi:
jacky~~~~~~~~~
推荐两个不错的mybatis GUI生成工具 -
masuweng:
(转)JAVA获得机器码的实现 -
albert0707:
有些扩展名为null
java 7中可以判断文件的contenttype了 -
albert0707:
非常感谢!!!!!!!!!
java 7中可以判断文件的contenttype了 -
zhangle:
https://zhuban.me竹板共享 - 高效便捷的文档 ...
一个不错的网络白板工具
1 闩锁
闩锁(Latch)的作用主要是保护数据的一致性。当很多会话用户请求同一个数据块时,要先获取闩锁才可以做动作。也就是说,当一个会话
用户要到数据库内找数据时,会先到数据库高速缓冲区中找,如果找不到表,就必须到数据文件中找。读出数据时,必须在数据库高速缓冲
区中获取足够的空闲空间,而要获取足够的空闲空间,会先去清理LRU List(把不常用的东西清出来);但要清理LRU List,必须先执行闩锁
操作,而对DB_BLOCK_ LRU_LATCHES参数的设置,表示决定使用几个闩锁。但基本上,闩锁的个数大于CPU的个数是没效益的
闩锁的个数是可以由DB_BLOCK_LRU_ATCHES参数设置的。
闩锁的最大值可以由以下两点决定:
CPU的个数×2。
DB Block Buffer/50。
以这两项中的最小的值来算。
2
DB_WRITER_PROCESSES
当数据库高速缓冲区需要读取或写回数据到数据文件中时,都需要通过DBWRn这个后台进程来协助处理,而DB_WRITER_PROCESSES主要就是设
置要由几个DBWRn来协助处理,最多可以达到10个。在此建议不要超过系统CPU的个数,如果设置的值超过了CPU的个数,那么超过的那些是
无法起作用的,
3 V$DB_CACHE_ADVICE
。当开启参数DB_CACHE_ADVICE后,经过一段时间,Oracle就会自动收集足够的相关统计数据,并预测出DB_CACHE_SIZE在不同大小情况下
的性能数据,而这些数据就是通过V$DB_CACHE_ADVICE视图来显示的,因此,可以根据这些数据对DB_CACHE_SIZE做相关的调整,以达到最佳
情况。
SELECT ADVICE_STATUS,
SIZE_FOR_ESTIMATE,
ESTD_PHYSICAL_READ_FACTOR,
ESTD_PHYSICAL_READS
FROM V$DB_CACHE_ADVICE
WHERE NAME = 'DEFAULT';
当ESTD_PHYSICAL_READ_FACTOR为1时,可以得出最好的cache分配内存。
4 V$BUFFER_POOL_STATISTICS
可以查询V$BUFFER_POOL_STATISTICS来查看每个数据库高速缓冲区的命中率,方式如下:
SQL> SELECT name,1 - (physical_reads / (db_block_gets + consistent_gets))
"HIT_RATIO" FROM sys.v$buffer_pool_statistics
WHERE db_block_gets + consistent_gets > 0;
对于SYS.V$BUFFER_POOL_STATISTICS,要先执行程序catclust.sql。
注意,原则上,获取命中率要在90%以上。
但回收率若是在90%以上,就代表这期间常用的数据是被放在回收池里的,而回收池里的数据又是经常被重复使用,所以,如果回收率是在
90%以上,就代表有问题,因为这代表90%以上的数据用完就丢了,应该将常用的数据放在保留池里。
5 共享池
共享池(Share Pool)主要是存放最近执行过的SQL语句、数据字典与PL/SQL的一些数据、表的定义和权限等,包含库缓存、数据字典高速
缓存、控制结构、可重用运行时内存等部分
1)库缓存
共享SQL区域:当执行一个SQL语句时,Oracle就会为每一句SQL打开一个游标(Cursor),并提供一个共享SQL区域和私有SQL区域空间用于
存放,当发现两个以上的会话在使用同一个SQL语句时,Oracle就会重新组织共享SQL区域,使这些会话用户能重复使用此区域的内容,从而
不浪费宝贵的资源,同时,还会在私有SQL区域里保存一份这个SQL语句的副本;反之,如果没有找到相同的SQL语句,就必须重新进行完整
的分析作业,并将分析树(Parse Tree)以及执行计划等存放在共享池内,以备下次使用。这时要注意的是,在Oracle于共享池中寻找相同的
SQL语句的过程中,如果使用的SQL语句有任何一个地方不相同,Oracle就会将此SQL语句视为在此共享池中找不到,所以需要重新进行分析
。因此,如果同一段SQL语句只是在条件的部分输入不同的值,Oracle也会认为SQL语句不同,为此,可使用绑定变量(Bind Variable),意
思是Oracle会将变动的值视为绑定变量,这样很容易在共享池里找到相同的SQL语句
当一条新的SQL语句被分析(Parse)时,Oracle从共享池中分配一块内存来存储共享SQL区域,而这块被分配的内存的大小与这条语句的复
杂性相关,如果共享池中的空间不够分配给共享SQL区域使用,Oracle就会启动LRU机制,将最近最少使用的内存块释放出来,直到有足够的
空间分配给新SQL语句的共享SQL区域;被释放出来的那块内存块内的SQL语句,如果再次被使用就必须重新分析,并重新分配共享SQL区域,
而这些动作都是比较消耗CPU的作业。这就是为何要使用绑定变量的原因了。因为如果没有使用绑定变量,当SQL语句中的变量的数值不同时
,Oracle就会将其视为一条新的语句,重复上面的分析、内存分配等动作,这都将大大消耗系统资源,降低Oracle系统性能。
2) 数据字典高速缓存
数据字典高速缓存是有关于数据库的参考信息、数据库的组织结构和数据库中的用户信息与权限等,而这些内容都是存储在表内,通常
以表和视图的形式进行呈现,就像经常使用到的V$xxx、DBA_xxx等系统的视图和表都是存储在数据字典(Data Dictionary)内。这里值得注
意的是,当SQL语句在分析的过程中时,也会去参考数据字典内的信息,而参考数据字典的动作所产生的SQL语句称为递归的SQL(Recursive
SQL),如果使用Statspack分析统计数据,此类的递归的SQL会被统计为Recursive Calls。
3)重要概念
基本上,共享池是依照修正过的LRU算法来判断其中的SQL语句与对象是否需要保留在共享池内。一般来说,当共享池需要为一个新的
SQL语句或对象分配内存时,会先确认是否有足够的空间,如果没有,就会将那些不经常使用的SQL语句和对象释放掉,也就是利用LRU机制
;但对于经常使用的SQL语句或对象,就会一直保留在共享池内。
除了LRU机制以外,当发生以下的情况时,Oracle也会将SQL语句从内存中释放出来:
当长时间没有被使用打开的游标(Open Cursor)时,SQL语句还是可能会从共享池中被释放出来,而此时如果还需要运行相关的SQL语句,
Oracle就会重新分析,并记录到共享SQL区域内。
当使用Analyze语句重新统计对象的信息时,所有与被分析对象相关的SQL语句都从共享池内被释放掉,这是因为重新分析对象,意味着原来
的执行计划可能不适用,所以必须将相关SQL语句都从共享池内释放掉,当再次使用到时,会重新分析并产生新的执行计划。
当对象的结构被修改过后,与该对象相关的所有共享SQL区域内都被注记为Invalid,当再次使用到相关的SQL语句时,就会再重新分析一次
。
Global Database Name被修改了,共享池内的所有信息都会被清空。
手动清空共享池的语句如下:
ALTER SYSTEM FLUSH SHARED_POOL;
当Oracle分析一个PL/SQL对象时,如过程、函数、触发器、包等,都需要从共享池中分配内存给这些对象。由于这些对象一般所占用的内存
空间都比较大,如包,因此分配的内存空间也相对较大,当Oracle经过长时间的运行后,共享池可能存在海量存储器碎片(Fragmentation)
,因而导致无法满足此类对象对于内存的需求。为了解决这类问题,Oracle专门从共享池内设置出一块共享的保留专用内存区域(Shared
Reserved Pool,简称保留区)来分配给这些具有内存需求的对象。这个保留区的默认值是共享池大小的5%,其大小一般建议是共享池的10%
,但绝对不要超过共享池大小的50%。除此之外,保留区的大小也可以通过参数SHARED_POOL_RESERVED_SIZE来调整,保留区的特点如下:
保留区是从共享池中分配,而不是直接从SGA中分配的,因此,保留区是共享池的一部分,用于存储大的对象。
在共享池中内存大于5 KB的对象就会被存放在共享池内的保留区,5 KB是默认值,而这个大小限制是可以通过隐藏参数
_SHARED_POOL_RESERVED_MIN_ ALLOC来设置的。除了在实例打开的过程中,所有小于这个数的对象永远都不会放到保留区,而大于这个值的
对象也永远不会存放到非保留区中。
当保留区有多余的内存空间时,对象也不会被放到共享池内的空间列表中,它有自己独立的保留空闭列表;相对的,当共享池空间不足时,
Oracle就利用LRU机制将不常用的对象释放,而不会影响到保留区内的对象。也就是说,保留区也是使用的LRU机制,但是在扫描时,其与共
享池是相互不影响的。
保留区内的信息可查询V$SHARED_POOL_RESERVED。关于V$SHARED_ POOL_RESERVED的详细内容,请参阅第2.3.5节。
前面提过Oracle在共享池中寻找相同的SQL语句的过程中,如果使用的SQL语句有任何一个地方不相同,Oracle就会视此SQL语句在此共享池
中找不到,所以需要重新进行分析,因此,若当同一段SQL语句只是在条件的部分输入了不同的值,Oracle也会将其视为不同的SQL语句,为
了适应这种情况,可使用绑定变量,但要如何判断SQL语句是否使用了绑定变量呢?可使用以下语句得知目前Hard Parse(硬分析)的次数与
比例,Hard Parse次数越少越好,所以比例值越接近于0越好。
select a.value as Total,b.value as "Hard Pase",
round(b.value / a.value, 2) as Ratio
from v$sysstat a, v$sysstat b
where a.name = 'parse count (total)' and b.name = 'parse count (hard)';
下面的语句查询哪些语句没使用变量绑定:
oracle 9/10:
select d.plan_hash_value plan_hash_value,
d.execntexecnt,
a.hash_valuehash_value,
a.sql_textsql_text
from v$sqltext a,
(select plan_hash_value, hash_value, execnt
from (select c.plan_hash_value,
b.hash_value,
c.execnt,
rank() over(partition by c.plan_hash_value order by
b.hash_value) as hashrank
from v$sql b,
(select count(*) as execnt, plan_hash_value
from v$sql
where plan_hash_value <> 0
group by plan_hash_value
having count(*) > 10
order by count(*) desc) c
where b.plan_hash_value = c.plan_hash_value
group by c.plan_hash_value, b.hash_value, c.execnt)
where hashrank <= 3) d
where a.hash_value = d.hash_value
order by d.execnt de SHARED_POOL_SIZEsc, a.hash_value, a.piece;
oracle 11g:
select d.plan_hash_value plan_hash_value,
d.execnt,
a.HASH_VALUE,
a.SQL_TEXT
from v$sqltext a,
(select plan_hash_value, hash_value, execnt
from (select c.plan_hash_value,
b.hash_value,
c.execnt,
rank() over(partition by c.plan_hash_value order by
b.hash_value) as hashrank
from v$sql b,
(select count(*) as execnt, plan_hash_value
from v$sql
where plan_hash_value <> 0
group by plan_hash_value
having count(*) > 10
order by count(*) desc) c
where b.plan_hash_value = c.plan_hash_value
group by c.plan_hash_value, b.hash_value, c.execnt)
where hashrank <= 3) d
where a.hash_value = d.hash_value
order by d.execnt desc, a.hash_value, a.piece;
6 共享池的重要参数
1) SHARED_POOL_SIZE
SHARED_POOL_SIZE指定了共享池的大小。在32位操作系统中,此参数的默认值是8 MB,而64位操作系统中的默认值是64 MB。
提示
Oracle 9i之前的版本和10g版本的共享池的算法是不相同的,差异如下:
Oracle 9i的算法是SHARED_POOL_SIZE的设置加上内部SGA消耗大小,因此,如果以SHOW PARAMETER SHARED_POOL_SIZE查询V$SGASTAT,并汇
总共享池的大小是不相同的。
Oracle 10g的算法是当设置了SHARED_POOL_SIZE的值,就将内部SGA消耗大小算在其中,因此,共享池真正使用的空间是SHARED_POOL_SIZE
的设置值减去内部SGA消耗大小。在10g中设置共享池的大小时必须加入这个因素,如果共享池的设置太小,在打开数据库时,将会有ORA-
0371的错误信息。
2)一般情况下,会发现保留区是很少被使用的,也就是说,5%~10%的保留区空间可能有些浪费。不过,建议经过长时间的观察再决定是否
需要调整保留区的大小。
V$SHARED_POOL_RESERVED的使用方式如下:
(1) 确认SHARED_POOL_RESERVED_SIZE的空间情况,查询语句如下:
SELECT ROUND(FREE_SPACE / 1024 / 1024, 1) "FREE SPACE MB",
REQUEST_MISSES,
REQUEST_FAILURES
FROM V$SHARED_POOL_RESERVED;
上结果的详细说明如下所示:
当REQUEST_FAILURES大于0时,增加SHARED_POOL_SIZE和SHARED_ POOL_RESERVED_SIZE的空间。
当REQUEST_MISS等于0,或是FREE_MEMORY大于等于SHARED_POOL_ RESERVED_SIZE的空间时,则增加SHARED_POOL_RESERVED_SIZE的空间。
(2) 确认SHARED_POOL_RESERVED_SIZE的命中率(Hit Ratio),查询语句如下:
SELECT (REQUEST_MISSES / (REQUESTS + 0.0001)) * 100 "REQUEST MISSES RATIO",
(REQUEST_FAILURES / (REQUESTS + 0.0001)) * 100 "REQUEST FAILURES RATIO"
FROM V$SHARED_POOL_RESERVED;
以上结果应该都要小于1%,如果大于1,应该加大SHARED_POOL_RESERVED_ SIZE
(3) V$SQL、V$SQLTEXT、V$SQLAREA与V$SQL_PLAN
V$SQL、V$SQLTEXT、V$SQLAREA与V$SQL_PLAN这4个视图都是查询在共享池中的SQL语句,而妥善的交互利用这些视图对于实例Tuning和
SQL Tuning有相当大的帮助。
V$SQL是共享池中已经分析过的SQL,其中列出了所有SQL的相关信息,但不包含GROUP BY语句,每一个SQL语句都是一笔数据,但此记录只保
留SQL语句的前1000个字符。
V$SQLAREA中记录了在共享池中分析过的每个SQL语句和准备运行的SQL语句的统计数据,和V$SQL一样只保留SQL的前1000个字符。
V$SQLTEXT视图会记录完整的SQL,但会将SQL分成不同笔的数据来存储。
V$SQL_PLAN视图包含了库缓存中所有游标所产生的执行计划,可结合V$SQLAREA获得库缓存中所有语句的查询计划。
V$SQL、V$SQLTEXT、V$SQLAREA与V$SQL_PLAN的运用如下所示:
利用V$SQL查询出使用频率最高的10句SQL:
select sql_text, executions
from (select sql_text,
executions,
rank() over(order by executions desc) exec_rank
from v$sql)
where exec_rank <= 10;
利用V$SQL查询出最耗费磁盘读的前10句SQL:
select disk_reads, sql_text
from (select sql_text,
disk_reads,
dense_rank() over(order by disk_reads desc) disk_reads_rank
from v$sql)
where disk_reads_rank <= 10;
利用V$SQL查询出最耗费内存的前10句逻辑读SQL语句:
select buffer_gets, sql_text
from (select sql_text,
buffer_gets,
dense_rank() over(order by buffer_gets desc) buffer_gets_rank
from v$sql)
where buffer_gets_rank <= 10;
利用V$SQLAREA和V$SQLTEXT查看消耗资源最多的SQL语句,步骤如下。
A SELECT hash_value, executions, buffer_gets, disk_reads, parse_calls
FROM V$SQLAREA
WHERE buffer_gets > 10000000 OR disk_reads > 1000000
ORDER BY buffer_gets + 100 * disk_reads DESC;
b 得到HASH_VALUE后,再利用V$SQLTEXT查询出实际的SQL语句。
select ADDRESS, HASH_VALUE, PIECE, SQL_TEXT
from v$sqltext
where hash_value = '2450129223'
order by PIECE;
利用V$SQLAREA查询出磁盘读次数超过100 000的查询语句,也就是最耗资源的SQL语句,语句如下:
select b.username "USER NAME",
a.disk_reads "DISK READ",
a.executions EXECUTIONS,
a.disk_reads / decode(a.executions, 0, 1, a.executions) "READ_EXEC%",
a.sql_text "SQL TEXT"
from v$sqlarea a, dba_users b
where a.parsing_user_id = b.user_id
and a.disk_reads > 100000
order by a.disk_reads desc;
利用V$SQL和V$SQL_PLAN查询出SQL语句的执行计划,步骤如下:
A 利用V$SQL查出查询的SQL语句的ADDRESS和HASH_VALUE,语句如下:
SELECT sql_text, address, hash_value FROM v$sql
WHERE sql_text like 'SELECT * FROM EMP %';
B 利用查出的ADDRESS和HASH_VALUE,配合V$SQL_PLAN相对应的字段,即可查询出此SQL语句的执行计划,语句如下;
SELECT operation, options, object_name, cost FROM v$sql_plan
WHERE address = '32557612' AND hash_value =2128902247;
利用V$SESSION的SQL_HASH_VALUE和SQL_ADDRESS字段,配合V$SQLTEXT的HASH_VALUE和ADDRESS,可查询出当前用户链接的SQL语句,步骤
如下
a 利用V$SESSION查询出SQL_HASH_VALUE和SQL_ADDRESS,语句如下
SELECT USERNAME,
TERMINAL, PROGRAM,
SQL_HASH_VALUE,
SQL_ADDRESS, TYPE
FROM V$SESSION
WHERE TYPE NOT LIKE 'BACKGROUND';
b 利用查出的SQL_HASH_VALUE和SQL_ADDRESS,再配合V$SQLTEXT相对应的字段即可,语句如下;
SELECT *
FROM V$SQLTEXT
WHERE HASH_VALUE = '889124229'
AND ADDRESS = '000000008EBE3A38'
ORDER BY PIECE;
(3) V$LIBRARYCACHE
V$LIBRARYCACHE的内容包含了关于库缓存的性能统计信息,对于共享池的性能优化有很大帮助
此表中必须特别注意PIN和GET的命中率或未命中率,当命中率小于99%或未命中率大于1%时,说明Hard Parse过多,可能需要加大共享池或是使用绑定变量等优化的动作。查询命中率的语句如下:
Select
namespace,
gets,
gethitratio*100 "GET%",
pins,
pinhitratio*100 "PIN%",
reloads,
invalidations
from
v$librarycache;
闩锁(Latch)的作用主要是保护数据的一致性。当很多会话用户请求同一个数据块时,要先获取闩锁才可以做动作。也就是说,当一个会话
用户要到数据库内找数据时,会先到数据库高速缓冲区中找,如果找不到表,就必须到数据文件中找。读出数据时,必须在数据库高速缓冲
区中获取足够的空闲空间,而要获取足够的空闲空间,会先去清理LRU List(把不常用的东西清出来);但要清理LRU List,必须先执行闩锁
操作,而对DB_BLOCK_ LRU_LATCHES参数的设置,表示决定使用几个闩锁。但基本上,闩锁的个数大于CPU的个数是没效益的
闩锁的个数是可以由DB_BLOCK_LRU_ATCHES参数设置的。
闩锁的最大值可以由以下两点决定:
CPU的个数×2。
DB Block Buffer/50。
以这两项中的最小的值来算。
2
DB_WRITER_PROCESSES
当数据库高速缓冲区需要读取或写回数据到数据文件中时,都需要通过DBWRn这个后台进程来协助处理,而DB_WRITER_PROCESSES主要就是设
置要由几个DBWRn来协助处理,最多可以达到10个。在此建议不要超过系统CPU的个数,如果设置的值超过了CPU的个数,那么超过的那些是
无法起作用的,
3 V$DB_CACHE_ADVICE
。当开启参数DB_CACHE_ADVICE后,经过一段时间,Oracle就会自动收集足够的相关统计数据,并预测出DB_CACHE_SIZE在不同大小情况下
的性能数据,而这些数据就是通过V$DB_CACHE_ADVICE视图来显示的,因此,可以根据这些数据对DB_CACHE_SIZE做相关的调整,以达到最佳
情况。
SELECT ADVICE_STATUS,
SIZE_FOR_ESTIMATE,
ESTD_PHYSICAL_READ_FACTOR,
ESTD_PHYSICAL_READS
FROM V$DB_CACHE_ADVICE
WHERE NAME = 'DEFAULT';
当ESTD_PHYSICAL_READ_FACTOR为1时,可以得出最好的cache分配内存。
4 V$BUFFER_POOL_STATISTICS
可以查询V$BUFFER_POOL_STATISTICS来查看每个数据库高速缓冲区的命中率,方式如下:
SQL> SELECT name,1 - (physical_reads / (db_block_gets + consistent_gets))
"HIT_RATIO" FROM sys.v$buffer_pool_statistics
WHERE db_block_gets + consistent_gets > 0;
对于SYS.V$BUFFER_POOL_STATISTICS,要先执行程序catclust.sql。
注意,原则上,获取命中率要在90%以上。
但回收率若是在90%以上,就代表这期间常用的数据是被放在回收池里的,而回收池里的数据又是经常被重复使用,所以,如果回收率是在
90%以上,就代表有问题,因为这代表90%以上的数据用完就丢了,应该将常用的数据放在保留池里。
5 共享池
共享池(Share Pool)主要是存放最近执行过的SQL语句、数据字典与PL/SQL的一些数据、表的定义和权限等,包含库缓存、数据字典高速
缓存、控制结构、可重用运行时内存等部分
1)库缓存
共享SQL区域:当执行一个SQL语句时,Oracle就会为每一句SQL打开一个游标(Cursor),并提供一个共享SQL区域和私有SQL区域空间用于
存放,当发现两个以上的会话在使用同一个SQL语句时,Oracle就会重新组织共享SQL区域,使这些会话用户能重复使用此区域的内容,从而
不浪费宝贵的资源,同时,还会在私有SQL区域里保存一份这个SQL语句的副本;反之,如果没有找到相同的SQL语句,就必须重新进行完整
的分析作业,并将分析树(Parse Tree)以及执行计划等存放在共享池内,以备下次使用。这时要注意的是,在Oracle于共享池中寻找相同的
SQL语句的过程中,如果使用的SQL语句有任何一个地方不相同,Oracle就会将此SQL语句视为在此共享池中找不到,所以需要重新进行分析
。因此,如果同一段SQL语句只是在条件的部分输入不同的值,Oracle也会认为SQL语句不同,为此,可使用绑定变量(Bind Variable),意
思是Oracle会将变动的值视为绑定变量,这样很容易在共享池里找到相同的SQL语句
当一条新的SQL语句被分析(Parse)时,Oracle从共享池中分配一块内存来存储共享SQL区域,而这块被分配的内存的大小与这条语句的复
杂性相关,如果共享池中的空间不够分配给共享SQL区域使用,Oracle就会启动LRU机制,将最近最少使用的内存块释放出来,直到有足够的
空间分配给新SQL语句的共享SQL区域;被释放出来的那块内存块内的SQL语句,如果再次被使用就必须重新分析,并重新分配共享SQL区域,
而这些动作都是比较消耗CPU的作业。这就是为何要使用绑定变量的原因了。因为如果没有使用绑定变量,当SQL语句中的变量的数值不同时
,Oracle就会将其视为一条新的语句,重复上面的分析、内存分配等动作,这都将大大消耗系统资源,降低Oracle系统性能。
2) 数据字典高速缓存
数据字典高速缓存是有关于数据库的参考信息、数据库的组织结构和数据库中的用户信息与权限等,而这些内容都是存储在表内,通常
以表和视图的形式进行呈现,就像经常使用到的V$xxx、DBA_xxx等系统的视图和表都是存储在数据字典(Data Dictionary)内。这里值得注
意的是,当SQL语句在分析的过程中时,也会去参考数据字典内的信息,而参考数据字典的动作所产生的SQL语句称为递归的SQL(Recursive
SQL),如果使用Statspack分析统计数据,此类的递归的SQL会被统计为Recursive Calls。
3)重要概念
基本上,共享池是依照修正过的LRU算法来判断其中的SQL语句与对象是否需要保留在共享池内。一般来说,当共享池需要为一个新的
SQL语句或对象分配内存时,会先确认是否有足够的空间,如果没有,就会将那些不经常使用的SQL语句和对象释放掉,也就是利用LRU机制
;但对于经常使用的SQL语句或对象,就会一直保留在共享池内。
除了LRU机制以外,当发生以下的情况时,Oracle也会将SQL语句从内存中释放出来:
当长时间没有被使用打开的游标(Open Cursor)时,SQL语句还是可能会从共享池中被释放出来,而此时如果还需要运行相关的SQL语句,
Oracle就会重新分析,并记录到共享SQL区域内。
当使用Analyze语句重新统计对象的信息时,所有与被分析对象相关的SQL语句都从共享池内被释放掉,这是因为重新分析对象,意味着原来
的执行计划可能不适用,所以必须将相关SQL语句都从共享池内释放掉,当再次使用到时,会重新分析并产生新的执行计划。
当对象的结构被修改过后,与该对象相关的所有共享SQL区域内都被注记为Invalid,当再次使用到相关的SQL语句时,就会再重新分析一次
。
Global Database Name被修改了,共享池内的所有信息都会被清空。
手动清空共享池的语句如下:
ALTER SYSTEM FLUSH SHARED_POOL;
当Oracle分析一个PL/SQL对象时,如过程、函数、触发器、包等,都需要从共享池中分配内存给这些对象。由于这些对象一般所占用的内存
空间都比较大,如包,因此分配的内存空间也相对较大,当Oracle经过长时间的运行后,共享池可能存在海量存储器碎片(Fragmentation)
,因而导致无法满足此类对象对于内存的需求。为了解决这类问题,Oracle专门从共享池内设置出一块共享的保留专用内存区域(Shared
Reserved Pool,简称保留区)来分配给这些具有内存需求的对象。这个保留区的默认值是共享池大小的5%,其大小一般建议是共享池的10%
,但绝对不要超过共享池大小的50%。除此之外,保留区的大小也可以通过参数SHARED_POOL_RESERVED_SIZE来调整,保留区的特点如下:
保留区是从共享池中分配,而不是直接从SGA中分配的,因此,保留区是共享池的一部分,用于存储大的对象。
在共享池中内存大于5 KB的对象就会被存放在共享池内的保留区,5 KB是默认值,而这个大小限制是可以通过隐藏参数
_SHARED_POOL_RESERVED_MIN_ ALLOC来设置的。除了在实例打开的过程中,所有小于这个数的对象永远都不会放到保留区,而大于这个值的
对象也永远不会存放到非保留区中。
当保留区有多余的内存空间时,对象也不会被放到共享池内的空间列表中,它有自己独立的保留空闭列表;相对的,当共享池空间不足时,
Oracle就利用LRU机制将不常用的对象释放,而不会影响到保留区内的对象。也就是说,保留区也是使用的LRU机制,但是在扫描时,其与共
享池是相互不影响的。
保留区内的信息可查询V$SHARED_POOL_RESERVED。关于V$SHARED_ POOL_RESERVED的详细内容,请参阅第2.3.5节。
前面提过Oracle在共享池中寻找相同的SQL语句的过程中,如果使用的SQL语句有任何一个地方不相同,Oracle就会视此SQL语句在此共享池
中找不到,所以需要重新进行分析,因此,若当同一段SQL语句只是在条件的部分输入了不同的值,Oracle也会将其视为不同的SQL语句,为
了适应这种情况,可使用绑定变量,但要如何判断SQL语句是否使用了绑定变量呢?可使用以下语句得知目前Hard Parse(硬分析)的次数与
比例,Hard Parse次数越少越好,所以比例值越接近于0越好。
select a.value as Total,b.value as "Hard Pase",
round(b.value / a.value, 2) as Ratio
from v$sysstat a, v$sysstat b
where a.name = 'parse count (total)' and b.name = 'parse count (hard)';
下面的语句查询哪些语句没使用变量绑定:
oracle 9/10:
select d.plan_hash_value plan_hash_value,
d.execntexecnt,
a.hash_valuehash_value,
a.sql_textsql_text
from v$sqltext a,
(select plan_hash_value, hash_value, execnt
from (select c.plan_hash_value,
b.hash_value,
c.execnt,
rank() over(partition by c.plan_hash_value order by
b.hash_value) as hashrank
from v$sql b,
(select count(*) as execnt, plan_hash_value
from v$sql
where plan_hash_value <> 0
group by plan_hash_value
having count(*) > 10
order by count(*) desc) c
where b.plan_hash_value = c.plan_hash_value
group by c.plan_hash_value, b.hash_value, c.execnt)
where hashrank <= 3) d
where a.hash_value = d.hash_value
order by d.execnt de SHARED_POOL_SIZEsc, a.hash_value, a.piece;
oracle 11g:
select d.plan_hash_value plan_hash_value,
d.execnt,
a.HASH_VALUE,
a.SQL_TEXT
from v$sqltext a,
(select plan_hash_value, hash_value, execnt
from (select c.plan_hash_value,
b.hash_value,
c.execnt,
rank() over(partition by c.plan_hash_value order by
b.hash_value) as hashrank
from v$sql b,
(select count(*) as execnt, plan_hash_value
from v$sql
where plan_hash_value <> 0
group by plan_hash_value
having count(*) > 10
order by count(*) desc) c
where b.plan_hash_value = c.plan_hash_value
group by c.plan_hash_value, b.hash_value, c.execnt)
where hashrank <= 3) d
where a.hash_value = d.hash_value
order by d.execnt desc, a.hash_value, a.piece;
6 共享池的重要参数
1) SHARED_POOL_SIZE
SHARED_POOL_SIZE指定了共享池的大小。在32位操作系统中,此参数的默认值是8 MB,而64位操作系统中的默认值是64 MB。
提示
Oracle 9i之前的版本和10g版本的共享池的算法是不相同的,差异如下:
Oracle 9i的算法是SHARED_POOL_SIZE的设置加上内部SGA消耗大小,因此,如果以SHOW PARAMETER SHARED_POOL_SIZE查询V$SGASTAT,并汇
总共享池的大小是不相同的。
Oracle 10g的算法是当设置了SHARED_POOL_SIZE的值,就将内部SGA消耗大小算在其中,因此,共享池真正使用的空间是SHARED_POOL_SIZE
的设置值减去内部SGA消耗大小。在10g中设置共享池的大小时必须加入这个因素,如果共享池的设置太小,在打开数据库时,将会有ORA-
0371的错误信息。
2)一般情况下,会发现保留区是很少被使用的,也就是说,5%~10%的保留区空间可能有些浪费。不过,建议经过长时间的观察再决定是否
需要调整保留区的大小。
V$SHARED_POOL_RESERVED的使用方式如下:
(1) 确认SHARED_POOL_RESERVED_SIZE的空间情况,查询语句如下:
SELECT ROUND(FREE_SPACE / 1024 / 1024, 1) "FREE SPACE MB",
REQUEST_MISSES,
REQUEST_FAILURES
FROM V$SHARED_POOL_RESERVED;
上结果的详细说明如下所示:
当REQUEST_FAILURES大于0时,增加SHARED_POOL_SIZE和SHARED_ POOL_RESERVED_SIZE的空间。
当REQUEST_MISS等于0,或是FREE_MEMORY大于等于SHARED_POOL_ RESERVED_SIZE的空间时,则增加SHARED_POOL_RESERVED_SIZE的空间。
(2) 确认SHARED_POOL_RESERVED_SIZE的命中率(Hit Ratio),查询语句如下:
SELECT (REQUEST_MISSES / (REQUESTS + 0.0001)) * 100 "REQUEST MISSES RATIO",
(REQUEST_FAILURES / (REQUESTS + 0.0001)) * 100 "REQUEST FAILURES RATIO"
FROM V$SHARED_POOL_RESERVED;
以上结果应该都要小于1%,如果大于1,应该加大SHARED_POOL_RESERVED_ SIZE
(3) V$SQL、V$SQLTEXT、V$SQLAREA与V$SQL_PLAN
V$SQL、V$SQLTEXT、V$SQLAREA与V$SQL_PLAN这4个视图都是查询在共享池中的SQL语句,而妥善的交互利用这些视图对于实例Tuning和
SQL Tuning有相当大的帮助。
V$SQL是共享池中已经分析过的SQL,其中列出了所有SQL的相关信息,但不包含GROUP BY语句,每一个SQL语句都是一笔数据,但此记录只保
留SQL语句的前1000个字符。
V$SQLAREA中记录了在共享池中分析过的每个SQL语句和准备运行的SQL语句的统计数据,和V$SQL一样只保留SQL的前1000个字符。
V$SQLTEXT视图会记录完整的SQL,但会将SQL分成不同笔的数据来存储。
V$SQL_PLAN视图包含了库缓存中所有游标所产生的执行计划,可结合V$SQLAREA获得库缓存中所有语句的查询计划。
V$SQL、V$SQLTEXT、V$SQLAREA与V$SQL_PLAN的运用如下所示:
利用V$SQL查询出使用频率最高的10句SQL:
select sql_text, executions
from (select sql_text,
executions,
rank() over(order by executions desc) exec_rank
from v$sql)
where exec_rank <= 10;
利用V$SQL查询出最耗费磁盘读的前10句SQL:
select disk_reads, sql_text
from (select sql_text,
disk_reads,
dense_rank() over(order by disk_reads desc) disk_reads_rank
from v$sql)
where disk_reads_rank <= 10;
利用V$SQL查询出最耗费内存的前10句逻辑读SQL语句:
select buffer_gets, sql_text
from (select sql_text,
buffer_gets,
dense_rank() over(order by buffer_gets desc) buffer_gets_rank
from v$sql)
where buffer_gets_rank <= 10;
利用V$SQLAREA和V$SQLTEXT查看消耗资源最多的SQL语句,步骤如下。
A SELECT hash_value, executions, buffer_gets, disk_reads, parse_calls
FROM V$SQLAREA
WHERE buffer_gets > 10000000 OR disk_reads > 1000000
ORDER BY buffer_gets + 100 * disk_reads DESC;
b 得到HASH_VALUE后,再利用V$SQLTEXT查询出实际的SQL语句。
select ADDRESS, HASH_VALUE, PIECE, SQL_TEXT
from v$sqltext
where hash_value = '2450129223'
order by PIECE;
利用V$SQLAREA查询出磁盘读次数超过100 000的查询语句,也就是最耗资源的SQL语句,语句如下:
select b.username "USER NAME",
a.disk_reads "DISK READ",
a.executions EXECUTIONS,
a.disk_reads / decode(a.executions, 0, 1, a.executions) "READ_EXEC%",
a.sql_text "SQL TEXT"
from v$sqlarea a, dba_users b
where a.parsing_user_id = b.user_id
and a.disk_reads > 100000
order by a.disk_reads desc;
利用V$SQL和V$SQL_PLAN查询出SQL语句的执行计划,步骤如下:
A 利用V$SQL查出查询的SQL语句的ADDRESS和HASH_VALUE,语句如下:
SELECT sql_text, address, hash_value FROM v$sql
WHERE sql_text like 'SELECT * FROM EMP %';
B 利用查出的ADDRESS和HASH_VALUE,配合V$SQL_PLAN相对应的字段,即可查询出此SQL语句的执行计划,语句如下;
SELECT operation, options, object_name, cost FROM v$sql_plan
WHERE address = '32557612' AND hash_value =2128902247;
利用V$SESSION的SQL_HASH_VALUE和SQL_ADDRESS字段,配合V$SQLTEXT的HASH_VALUE和ADDRESS,可查询出当前用户链接的SQL语句,步骤
如下
a 利用V$SESSION查询出SQL_HASH_VALUE和SQL_ADDRESS,语句如下
SELECT USERNAME,
TERMINAL, PROGRAM,
SQL_HASH_VALUE,
SQL_ADDRESS, TYPE
FROM V$SESSION
WHERE TYPE NOT LIKE 'BACKGROUND';
b 利用查出的SQL_HASH_VALUE和SQL_ADDRESS,再配合V$SQLTEXT相对应的字段即可,语句如下;
SELECT *
FROM V$SQLTEXT
WHERE HASH_VALUE = '889124229'
AND ADDRESS = '000000008EBE3A38'
ORDER BY PIECE;
(3) V$LIBRARYCACHE
V$LIBRARYCACHE的内容包含了关于库缓存的性能统计信息,对于共享池的性能优化有很大帮助
此表中必须特别注意PIN和GET的命中率或未命中率,当命中率小于99%或未命中率大于1%时,说明Hard Parse过多,可能需要加大共享池或是使用绑定变量等优化的动作。查询命中率的语句如下:
Select
namespace,
gets,
gethitratio*100 "GET%",
pins,
pinhitratio*100 "PIN%",
reloads,
invalidations
from
v$librarycache;
发表评论
-
mybatis generator中的字段大小写生成问题
2017-10-22 19:35 11421mybatis generator插件中,如果 mysql数据 ... -
MySQL统计一个列中不同值的数量
2017-07-11 14:04 16302https://yiqiwuliao.com/post/mys ... -
mysql 1449 : The user specified as a definer ('root'@'%') does not exist 解决方法
2017-03-02 09:44 1815权限问题,授权 给 root 所有sql 权限 mysql ... -
几个不错的MYSQL 优化TIPS
2016-11-19 12:30 824图片来自http://imysql.com/的PDF分享 [ ... -
powerdesign 逆向ORACLE的坑
2016-09-27 17:08 581要注意的是,在WIN 64中,如果要用powerdesin 来 ... -
( 转)mysql中删除两条重复记录中的一条
2015-10-19 20:19 1345| id | createTime | labId | pub ... -
mysql中sql语句=,>的时候的索引设置
2015-05-02 12:27 1319在 https://www.percona.com/blog/ ... -
mysql中profile的使用
2015-04-30 11:11 2240mysql 的 sql 性能分析器主要用途是显示 sql 执行 ... -
mysql中的sql mode
2015-04-13 11:29 1167mysql sql mode小结 1 sql mode可以 ... -
PROCEDURE ANALYSE()为mysql提高性能提供建议
2015-04-02 16:37 1488procedure analyse();语法如下 select ... -
mongodb中意外退出的问题
2015-02-11 14:32 1347mongodb启动的时候,意外退出: Unclean shut ... -
mysql 5.5中保留字查询
2014-06-05 23:16 1500mysql 5.5中保留字查询 http://www.5is ... -
(转)oracle 临时表空间的增删改查
2014-03-18 12:44 1159oracle 临时表空间的增删改查 1、查看临时表空间 (d ... -
pl-sql developer安装
2014-02-07 09:16 1146一直都是机器本机上有oracle,所以装pl sql deve ... -
oracle中的nvl,nvl2等参数
2013-12-26 11:18 23021.nul函数将一个null值转换为一个实际的值。 数据类型可 ... -
Oracle中的ROWNUM rowid 以及MySQL中实现rownum功能类似的语句
2013-12-26 11:08 2372http://gong-10140.iteye.com/blo ... -
ORACLE XE版本的限制
2013-12-07 08:11 369010g中用户数据最大为4G, 11G中最大为11G,如果超出大 ... -
oracle中监控索引是否可用
2013-11-04 07:22 1096在oracle中,可以使用如下的方法监控索引是否可用: a ... -
mysql 5.6中的时间类型的新精度介绍
2013-10-28 09:33 8427留意到mysql 5.6中,可以使用select now(6) ... -
<<oracle索引技术》读书笔记1
2013-08-25 16:23 1337expert indexing in oracle datab ...
相关推荐
资源名称:Oracle学习笔记-日常应用、深入管理、性能优化内容简介:Oracle学习笔记-日常应用、深入管理、性能优化Oracle 11g是最具代表性的高端关系型数据库管理系统,它在世界各地的大型商务数据库应用系统中被广泛...
但我可以根据标题“涂抹Oracle 三思笔记之一步一步学Oracle”和给定的相关知识点要求,构造一篇关于Oracle数据库学习的基础知识点文章,以满足您的需求。 Oracle数据库是全球范围内广泛使用的企业级关系数据库管理...
Oracle SQL是数据库管理员和开发人员在Oracle数据库系统中进行数据查询和管理的重要工具。这篇笔记主要涵盖了Oracle SQL的...这两份“Oracle SQL笔记”文档应包含了上述各个方面的详细解释和实例,值得仔细阅读和学习。
在数据库管理方面,分区技术是《Oracle8i数据库管理员手册》中探讨的重要内容之一。通过分区技术,管理员可以将大型数据表拆分成更小、更易于管理的部分,这种拆分有助于提升查询效率,尤其是在数据量极大的情况下。...
对于初学者来说,这是一个很好的学习资源,因为它能够帮助他们通过观看视频和阅读笔记的方式来加深理解。 描述中提到这些笔记“适合初学者的Oracle教材”,意味着内容应该是按照由浅入深的顺序进行编排,初学者可以...
这些只是Oracle 11g R2学习笔记中的部分内容,实际学习和使用中还会涉及更多如索引、触发器、存储过程、事务管理、性能优化等复杂主题。对于深入理解和掌握Oracle数据库,建议进一步阅读官方文档和其他专业资料,...
Oracle数据库是全球广泛使用的大型关系型数据库管理系统之一,其核心技术涉及数据存储、查询优化、并发控制、事务处理等多个方面。...通过阅读和理解这些读书笔记,可以提升对Oracle数据库的理解和操作能力。
这个名为"涂抹Oracle—三思笔记之一步一步学Oracle.zip"的压缩包文件,包含了该系列的学习资料,特别适合数据库学习者和运维开发人员提升Oracle技能。 PDF文档可能涵盖了以下几个关键知识点: 1. **Oracle基础**:...
标题中提到的“ORACLE DBA工作笔记 运维数据迁移与性能调优”揭示了这本书籍主要围绕着Oracle数据库管理员(DBA)在日常工作中经常需要进行的两项关键任务:数据迁移和性能调优。作为一名Oracle DBA,不仅要负责...
Oracle是世界上最广泛使用的数据库管理系统之一,它提供了丰富的功能和组件,包括数据存储、查询优化、安全性、并发控制等。以下是对Oracle学习笔记中提到的一些关键知识点的详细解释: 1. **SQL执行顺序**: SQL...
《我的读书笔记(Oracle)个人版》是我个人在深入学习Oracle数据库系统过程中积累的心得体会,这份文档旨在为初学者提供一个清晰、易懂的Oracle入门教程。Oracle数据库是全球广泛应用的关系型数据库管理系统,尤其在...
Oracle数据库系统是世界上最广泛使用的数据库管理系统之一,尤其在企业级应用中占据主导地位。这份"Oracle实用笔记 命令 文档 PDF"很可能是对Oracle数据库管理、查询和维护的一份详细指南,涵盖了各种关键的Oracle...
Oracle数据库是世界上最流行的数据库管理系统之一,特别适用于大型企业级应用。本教程读书笔记主要涵盖了Oracle的基础知识,适合初学者入门。以下是对笔记内容的详细解释: 1. **表的命名和访问**: - 表的全名由`...
从给定的文件片段来看,内容似乎是乱码或者编码错误,但标题和描述明确指向了“《oracle9i数据库管理员手册》读书笔记”。基于这一点,我们可以聚焦于Oracle 9i数据库管理的关键知识点进行深入探讨。 ### Oracle 9i...
这篇学习笔记将带你深入理解Oracle11g的核心概念和技术,帮助你踏上数据库管理的成功之路。 首先,Oracle11g的基础部分涵盖了数据库安装、配置与管理。在安装过程中,你需要了解如何选择合适的安装选项,如企业版或...
Oracle数据库是全球最广泛使用的商业关系型数据库管理系统之一,由美国甲骨文公司(Oracle Corporation)开发和维护。李兴华的Oracle课堂笔记全面涵盖了Oracle数据库的基础知识、高级特性和管理技巧,对于学习和理解...
以下是对这些阅读笔记的详细解读: 1. **数据仓库与 OLTP 系统的对比**: 数据仓库(Data Warehouse)和在线事务处理(OLTP)系统是两种截然不同的数据库应用场景。OLTP系统主要服务于实时业务操作,强调高并发的...
这份笔记全面覆盖了Oracle数据库的基础知识、核心概念以及高级特性,旨在帮助读者系统地掌握Oracle数据库的管理和开发技能。 首先,Oracle数据库是一个关系型数据库管理系统(RDBMS),由甲骨文公司开发,广泛应用...
【标签】"源码"和"工具"暗示这份笔记可能包含了关于Oracle数据库的编程实践,比如PL/SQL(Oracle的数据库编程语言)的源代码示例,或者是使用Oracle开发工具如SQL Developer进行数据库管理和开发的技巧。源码可能...
Oracle数据库是全球最广泛使用的商业关系型数据库管理系统之一,它由甲骨文公司开发和维护...通过阅读“个人学习Oracle笔记.txt”文件,你可以期望找到对这些概念的详细解释和实例,帮助你在Oracle学习之旅上取得进展。