使用SQL 查看Shared Pool问题

潜在问题的SQL语句。这些语句的输出最好spool到一个文件中。

注意:这些语句可能会使latch竞争加剧,我们在上面的"使用 V$ 视图 (V$SQL 和 V$SQLAREA)" above.


查找literal SQL


SELECT substr(sql_text,1,40) "SQL", 
                count(*) , 
                sum(executions) "TotExecs"
 FROM v$sqlarea
 WHERE executions < 5
 GROUP BY substr(sql_text,1,40)
 HAVING count(*) > 30
 ORDER BY 2;


这个语句有助于找到那些经常被使用的literal SQL




检索Library Cache hit ratio



SELECT SUM(PINS) "EXECUTIONS",
 SUM(RELOADS) "CACHE MISSES WHILE EXECUTING"
 FROM V$LIBRARYCACHE;


如果misses/executions高于1%的话,则需要尝试减少library cache miss的发生。


改造:

SELECT SUM(PINS) "EXECUTIONS",
SUM(RELOADS) "CACHE MISSES WHILE EXECUTING", 
SUM(RELOADS)/SUM(PINS)
 
FROM V$LIBRARYCACHE;



检查hash chain的长度


SELECT hash_value, count(*) 
  
 FROM v$sqlarea 
  
 GROUP BY hash_value 
  
 HAVING count(*) > 5;


这个语句正常应该返回0行。如果有任何HASH_VALUES存在高的count(两位数的)的话,你需要查看是否是bug的影响或者是literal SQL使用了不正常的形式。建议进一步列出所有有相同HASH_VALUE的语句。例如:



SELECT sql_text FROM v$sqlarea WHERE hash_value= ;



有可能不同的SQL文本会映射到相同的hash值,比如:在7.3中,如果一个值在语句中出现2次而且中间正好间隔32个字节的话,这两个语句会映射出相同的hash值。





检查高版本



SELECT address, hash_value, 
  
                version_count , 
  
                users_opening , 
  
                users_executing, 
  
                substr(sql_text,1,40) "SQL" 
  
 FROM v$sqlarea 
  
 WHERE version_count > 10;


在上面的"Sharable SQL"章节中,我们已经描述了,一个语句的不同"版本"是当语句的字符完全一致但是需要访问的对象或者绑定变量不一致等等造成的。在Oracle8i的不同版本中因为进度监控的问题也会产生高版本。在这篇文档的前面描述过了,我们可以把_SQLEXEC_PROGRESSION_COST 设成'0'来禁止进度监控产生高版本。





找到占用shared pool 内存多的语句


SELECT substr(sql_text,1,40) "Stmt", count(*), 
  
                sum(sharable_mem) "Mem", 
  
                sum(users_opening) "Open", 
  
                sum(executions)       "Exec" 
  
 FROM v$sql 
  
 GROUP BY substr(sql_text,1,40) 
  
 HAVING sum(sharable_mem) > & 
  MEMSIZE;


这里 MEMSIZE取值为shared pool大小的10%,单位是byte。这个语句可以查出占用shared pool很大内存的那些SQL,这些SQL可以是相似的literal语句或者是一个语句的不同版本。





导致shared pool 内存'aged' out的内存分配



SELECT * 
  
 FROM x$ksmlru 
  
 WHERE ksmlrnum>0;



因为这个查询在返回不超过10行记录后就会消除X$KSMLRU的内容,所以请用SPOOL保存输出的内容。X$KSMLRU表显示从上一次查询该表开始,哪些内存分配操作导致了最多的内存块被清除出shared pool 。有些时候, 这会有助于找到那些持续的请求分配空间的session或者语句。 如果一个系统表现很好而且共享SQL 使用得也不错,但是偶尔会变慢,这个语句可以帮助找到原因。关于X$KSMLRU 的更多信息请查看Note:43600.1。





在不同Oracle Releases中的都会遇到的问题



在不同的release中有一些通用的会影响shared pool性能的问题:

>增加每个CPU的处理能力可以减少latch被持有的时间从而有助于在Oracle的各个release上减少shared pool竞争。换一个更快的CPU一般来说会比增加一个慢的CPU效果要好。

>如果你设置了一个EVENT,不管基于什么原因,请让Oracle support检查这个event是否会对shared pool的性能造成影响。

>确保Oracle实例有足够的内存,避免SGA内存被操作系统swap交换出去的风险。

例如: 在AIX上操作系统的不正确设置可能会导致 shared pool问题- 参考Note:316533.1