oracle学习笔记 SQL语句解析类型_硬解析_软解析

oracle学习笔记

SQL语句解析类型_硬解析_软解析

shared pool在讲oracle体系结构概述时讲了大体是干什么的,
这节把一些细节讲一下。

一)软件出问题

在oracle新的版本中,
特别从oracle 10g开始shared pool的问题慢慢变少了,
这和我们越来越关注它有关系。
但是shared pool实际的工作中还是经常出问题。

软件出问题是一个正常现象,
因为想让一个软件对每一个要求都做出正确的反应,几乎是无法实现的。
所以它会出问题。
比如一个windows程序,要把它直接放到linux系统中并让它正常运行,这是做不到的。

打补丁是修复问题的一种方式。
是在程序编写完成,在使用过程中发生了错误,
它不是什么致命错误,也不需要整体对程序进行改动,
这时程序员对程序进行一些小的修补,使这个错误不再发生。
一个补丁只能纠正很少的问题,并不是万全的方式。
这时程序仍然在出问题。

程序升级和打补丁类似,
但它是想向程序添加新的功能,
是对程序按自己的意图进行修改和添加代码,
这样很可能破坏原有程序的意图和功能,
也会造成软件出新的问题。
这时再来解决新的问题,又有可能造成进一步的破坏,
这样很可能进入恶性循环。
即使你的升级很少出错误,也未必比原有程序更好用。

我们对待问题的态度应该是:
它是避免不了的,
我们只能减少出问题,
并且减少问题是一个积累的过程。
使程序完善是一个千锤百炼的过程。

这是程序本身的问题,
还有用户对程序不熟出的不会用的问题,
是程序太深奥,用户不理解,
只能通过学习解决。

经常有学生和客户给老师发一些邮件,很多是关于shared pool的问题。

为什么shared pool出问题,他们无法解决,没有思路呢?
原因是他们对shared pool根本不了解。

shared pool出问题,百分之七八十以上特别是现在,都是因为oracle的补丁没有打。
很多问题都是补丁的问题。

这节课后解决一般的shared pool的问题,应该不大。

当你碰到sharedpool问题的时候,
第一时间马上去查一下metalink。
在metalink里面
对sharedpool一些常见的问题、以及所需要的补丁
会提供相关的文章和补丁。
到时候大家可以解决一下。

老师此前碰到的很多sharedpool的问题,大部分通过补丁来实现。

oracle补丁、补丁集叫opatch。

二)sharedpool结构

sharedpool最主要的一个作用是缓存sql语句、以及sql语句的执行计划

sql语句执行分三个阶段
第一阶段 解析
第二阶段 执行
第三阶段 获取数据。

解析 叫 parse
就是将一个sql语句解析成执行计划
执行 叫 execute
执行sql语句会获取到数据
获取的数据返给用户 叫 fetch

shared pool在解析部分有意义。

今天详细的剖析一下shared pool。

sharedpool是一块内存池,里面有会分成很多小的区块
每个块有不同的作用

我们研究主要研究sharedpool的三块三个部分

第一块 free部分
也就是sharedpool的空闲空间
比如给sharedpool分了1G的空间,它用了500M,还剩500M是free
另外一块叫 library cache 库缓存
主要缓存的是sql语句以及sql语句所对应的执行计划,这是研究的重点
第三块 字典缓存 row cache

三)数据字典

oracle数据库中有数据字典
我们在学习oracle数据库时我们一直地在使用数据字典。

oracle数据库自身的信息,都存储在数据字典里。
数据库里有多少表,有多少用户,表有多少列,列的名字是什么,
列的数据类型是什么,每个表多大...
这些信息都属于数据库自身信息,
这些自身信息,我们在管理数据库的时候,我们会经常用到数据字典。
因为我们管理数据库,
必须知道数据库里面有什么,这些对象的状态。

演示一下:
SQL> create table t1 as select * from dba_objects;

Table created.

建立一个新表t1和dba_objects表是一样的。
然后看什么是数据字典信息

假设现在我们什么都不知道,我们登录到数据库里面去,
想知道数据库里面有没有t1这张表,这时就需要用到数据字典

先查看一下dba_tables表的结构
SQL> desc dba_tables;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 OWNER                                     NOT NULL VARCHAR2(30)
 TABLE_NAME                                NOT NULL VARCHAR2(30)
 TABLESPACE_NAME                                    VARCHAR2(30)
 CLUSTER_NAME                                       VARCHAR2(30)
 IOT_NAME                                           VARCHAR2(30)
 STATUS                                             VARCHAR2(8)
 PCT_FREE                                           NUMBER
 PCT_USED                                           NUMBER
 INI_TRANS                                          NUMBER
 MAX_TRANS                                          NUMBER
 INITIAL_EXTENT                                     NUMBER
 NEXT_EXTENT                                        NUMBER
 MIN_EXTENTS                                        NUMBER
 MAX_EXTENTS                                        NUMBER
 PCT_INCREASE                                       NUMBER
 FREELISTS                                          NUMBER
 FREELIST_GROUPS                                    NUMBER
 LOGGING                                            VARCHAR2(3)
 BACKED_UP                                          VARCHAR2(1)
 NUM_ROWS                                           NUMBER
 BLOCKS                                             NUMBER
 EMPTY_BLOCKS                                       NUMBER
 AVG_SPACE                                          NUMBER
 CHAIN_CNT                                          NUMBER
 AVG_ROW_LEN                                        NUMBER
 AVG_SPACE_FREELIST_BLOCKS                          NUMBER
 NUM_FREELIST_BLOCKS                                NUMBER
 DEGREE                                             VARCHAR2(10)
 INSTANCES                                          VARCHAR2(10)
 CACHE                                              VARCHAR2(5)
 TABLE_LOCK                                         VARCHAR2(8)
 SAMPLE_SIZE                                        NUMBER
 LAST_ANALYZED                                      DATE
 PARTITIONED                                        VARCHAR2(3)
 IOT_TYPE                                           VARCHAR2(12)
 TEMPORARY                                          VARCHAR2(1)
 SECONDARY                                          VARCHAR2(1)
 NESTED                                             VARCHAR2(3)
 BUFFER_POOL                                        VARCHAR2(7)
 ROW_MOVEMENT                                       VARCHAR2(8)
 GLOBAL_STATS                                       VARCHAR2(3)
 USER_STATS                                         VARCHAR2(3)
 DURATION                                           VARCHAR2(15)
 SKIP_CORRUPT                                       VARCHAR2(8)
 MONITORING                                         VARCHAR2(3)
 CLUSTER_OWNER                                      VARCHAR2(30)
 DEPENDENCIES                                       VARCHAR2(8)
 COMPRESSION                                        VARCHAR2(8)
 DROPPED                                            VARCHAR2(3)

dba_tables就是个数据字典表
这里面放的信息就是数据字典信息
比如系统有多少表。

SQL> select table_name,owner from dba_tables where table_name like 'T1%';


TABLE_NAME                     OWNER
------------------------------ ------------------------------
T1                             SYS

我们看系统里有T1这张表,
T1这张表属于sys用户

dba_tables这个表就属于字典信息表
它里面放的信息,就是数据库系统自身的信息

这时我们会对oracle数据库里面字典信息很感兴趣。

我们经常在oracle数据库装完以后,不知道怎么使用。
要使用oracle,要先了解oracle内部的信息
oracle内部的信息全部在数据字典里面

我们先看一个资料oracle官方文档
oracle10g的官方文档编号为B19306_01
文档整体为网页形式

在其中找到 Reference(参考) 部分
并将其打开
网页上列出了很多oralce相关信息的数据字典的内容。

刚才使用的 DBA_TABLES 就在其中
点击链接后 
说它和表ALL_TABLES是一样的
进入ALL_TABLES的说明网页
列出了这两个表的内容信息
包括表有多少列,
这个表相关的视图
这个表放的什么信息
每列的数据类型是什么,含义是什么
都写的很详细

仔细翻看网页会发现它和 USER_TABLES 表的结构也基本一致

我们在使用时,可以在此查询
查一下有多少列,每列是什么含义
就可以使用了。
官方文档对此说明很详细。

oracle有非常多内容的数据字典

一个oracle DBA
对oracle数据库到底掌握到什么程度
一个很经典的标志就是他知道、了解、熟悉多少数据字典
因为数据字典研究的越透
对oralce了解的越深

老师以前学习的时候
老师的师傅总是给老师们讲
你把哪些oracle数据库数据字典表搞熟了才能进行下一步的学习。
导致老师经常在背数据字典表

我们以后学习中会经常补充讲各种各样的数据库字典表

数据字典先演示到这个地方。

四)shared pool内容大小

shared pool有三块内容

1 free空间
是shared pool的自由空间
2 library cache
缓存的主要是sql语句和sql语句的执行计划
3 row cache
里面缓存的是字典信息

我们看一下shared pool里面这三块内容分别是多大

先看一下library cache空间
SQL> select * from v$sgastat a where a.NAME = 'library cache';


POOL         NAME                            BYTES
------------ -------------------------- ----------
shared pool  library cache                 4936820

几乎没有空间仅仅5M
因为现在几乎没有什么业务负载,shared pool的library cache很小

再看一下free空间
SQL> select * from v$sgastat a where a.pool = 'shared pool' and a.NAME = 'free memory';


POOL         NAME                            BYTES
------------ -------------------------- ----------
shared pool  free memory                  15889120

也不大16M

再看一下row cache空间
SQL> select * from v$sgastat a where a.NAME = 'row cache';


POOL         NAME                            BYTES
------------ -------------------------- ----------
shared pool  row cache                     3741868

只有4M

因为数据库现在基本没什么负载,shared pool的空间都比较小。

五)sql语句解析过程

一个sql语句进来后分三个阶段
1解析 2执行 3 获取

解析的过程主要用的sharedpool,讲sharedpool时必然会讲到解析。

oracle的解析有两种解析或者说有三种解析
老师这里给大家讲两种解析。
1硬解析 2 软解析
还有一种解析叫软软解析也叫不解析

一个sql语句进入到数据库里以后
serverprocess会拿着sql语句
到sharedpool的library cache里面
去看一下这个sql语句以前有没有被解析过
也就是librarycache里面有没有这条sql语句和它对应的执行计划 
如果有的话 我们就不需要解析
但是今天讲的话会发现我们还是需要解析,需要软解析
如果这条sql语句在librarycache里面没有,这时候oracle会进行硬解析。

硬解析翻译成英文叫hardparse
软解析叫softparse

一条sql语句进来以后,
在librarycache里面如果没有缓存,就要进行硬解析。
如果有缓存,就会软解析。

1)硬解析包含的步骤

1、首先来讲
serverprocess首先判断这条sql语句语法有没有错误,这是必须的
2、这条sql语句里面所涉及的对象存不存在
比如sql语句访问某个表,这个表到底有没有
3、执行这条sql语句的用户对这个表、对相关的对象有没有权限
有没有系统权限、对象权限
在这些都满足的前提下
然后再进行下一步就是生成具体的执行计划

一条sql语句它有n种执行方案
有多种执行方案都可以完成sql语句
有的执行方案特点是消耗资源大速度慢
有的执行方案消耗资源小速度快

所以说
oracle要在这些sql语句所对应的n个执行方案里面
挑出一个最优的执行方案
然后作为这条sql语句的执行计划

这时硬解析里面最重要 也是最消耗资源的一步
这步几乎消耗oracle执行这条sql语句所消耗资源的全部。
它消耗资源我们可以认为是70%以上。

有了执行计划,就可以执行了

2)软解析也对应很多内容

1、sql语句语法
2、sql语句软解析主要判断这条sql语句所对应的一些对象的权限有没有、满不满足

硬解析也要完成这些内容,软解析也要做这些事情

它们的差别
软解析只是做一些常规判断
并不去做
从一个sql语句的n种执行方案中去挑出一个最优的执行方案作为这个sql语句的执行计划这步
这步软解析省了,这步最消耗资源。

如果是软解析
即使他还执行了很多步,但最消耗资源的一步它没有执行。
但软解析还是要消耗一部分资源,
硬解析最消耗资源

3)提一下软软解析

所谓的软软解析,就是不解析。
需要设置session_cached_cursors参数
其值是会话可以缓存的游标的数量

软软解析只在同一个会话中发生
当某个session第三次执行相同的SQL语句时,
会把该SQL语句的游标信息转移到该session的PGA中缓存起来

这样同一个serverprocess中再执行同一个sql语句
就会通过游标直接从librarycache中拿出执行计划
而不进行任何解析的步骤。

我们再回顾一下:

一条sql语句进来以后
serverprocess拿着这条sql语句到librarycache里面去找
如果这个sql语句在librarycache里面没有
说明这个sql语句以及对应的执行计划在librarycache里面没有
这时候发生硬解析
如果这个sql语句以及对应的执行计划在librarycache里面有
这个时候就发生软解析

硬解析和软解析发生的情况不一样
同时它俩执行的是有区别的。

硬解析消耗资源
软解析消耗资源非常少
我们希望软解析越多越好
尽量的不要产生硬解析

无论是软解析还是硬解析
在解析过程中都用到了好多数据库自身信息,
如:权限信息、对象信息、对象存不存在的信息、还包括对象里面的一些统计信息。
我们说这些信息是字典信息
解析都要频繁的访问数据字典信息
所以oracle就干脆把数据库字典信息放到sharedpool里面去,
让它和librarycache在一起。
还是有意义的!

老师前面描述的硬解析和软解析步骤已经够我们在实际工作中使用了,
没必要研究太深。

六)一些解析数据

我们访问v$sysstat
SQL> select name,value from v$sysstat where name like 'parse%';


NAME                                                                  VALUE
---------------------------------------------------------------- ----------
parse time cpu                                                          597
parse time elapsed                                                     3218
parse count (total)                                                   65402
parse count (hard)                                                     7635
parse count (failures)                                                    0

parse count (total)是数据库自启动以来总共发生的解析的总次数。
包括软解析和硬解析
一共发生了 65402次

parse count (hard)为硬解析数目为7635次

软解析数就是
parse count (total)-parse count (hard)=65402-7635=57767
发现硬解析比较少软解析比较多。

parse count (failures) 为解析失败次数
如sql语法写错了,都划到了解析失败里面去。

parse count (failures)量比较大有问题
parse count (hard)量比较大也有问题。
parse count (total)量比较大说明执行的sql语句比较多。
这是没有办法的。

parse time elapsed 
为解析花费的总时间
parse time cpu
为解析花费的cpu时间

一条语句解析的总时间要大于耗费的cpu时间
因为在解析时它还可能要做另外一些事情比如等待IO的时间等

我们通过访问v$sysstat 我们知道oracle自启动以来的解析的一个情况。

这个章节主要讲的是软解析和硬解析,
下一节讲sharedpool内存块的具体情况。


   2016年7月28日  
文字:韵筝

你可能感兴趣的:(oracle学习笔记,oralce学习,oralce,甲骨文,甲骨文学习笔记)