SQL语句分为两部分,静态部分与动态部分。
静态就是表名称,列名等;
动态是字面值;
where name='hsj'的where name是静态部分,hsj是动态部分。静态数量有限,动态变化万千。
静态部分对解析的影响远大于动态部分,对于相同的静态部分的SQL语句,一般执行计划是一样的。
动态部分用绑定变量,就能容易找到相同的SQL语句,效率就高。
shared pool的内存结构
库缓存libarary cache(交换频繁)
数据字典缓存dictionary cache(不太交换)
libarary cache存放了最近执行的SQL语句,存储过程,函数,解析树与执行计划等。
dictionary cache存放在执行SQL语句过程中参考的数据字典的信息,如表名,列名,权限等,数据以数据行存储,而不是数据
块,所以又叫row cache。
shared pool由内存块chunk组成
四种chunk:越向下越难被重用
1.free 空白chunk,可以不受限制地分配
2.recr 有内容的chunk,比如很多共享SQL语句的chunk是recreatable。但可以拿来用,需要再重建。
3.freeabl 处理过程中间产生的,移走的话无法被重建。
4.perm permanent,chunk包含永久对象;
chunk空白时不属于library cache又不属于dictionary cache,再被哪个用就属于哪个。
shared pool中,free类型的chunk串成可用链表(Freelist),如果某个进程发现freelist上的chunk不够用,就从recr链表中释
放掉部分chunk,加入到freelist中。
ORACLE8i之后,为减轻shared pool latch争用问题,大大增加了freelist数量。
当SQL语句进入Library cache时,ORACLE会到dictionary cache中去找与sharedpool_test表有关的数据字典信息,比如表名,列
,用户权限。如果发现没有,则会将system表空间里的数据字典信息调入buffer cache,读取数据块里关于数据字典的内容,再将这些内
容按行的形式放入dictionary cache里。
SQL语句解析过程,硬解析与软解析。一条SQL首次执行时必须硬解析。
当客户端发出一条SQL语句,进入shared pool,Oracle将SQL文本转换成ASCII值,再根据hash函数计算其对应的hash值,再到
library cache中找到相应的bucket,再找出是否存在该SQL语句。
如果不存在,则先获得shared pool latch,然后在freelist中找到可用的chunk,然后这些chunk就认为是进入了library cache
了。接下来是硬解析。
硬解析:1,对SQL语句进行文法检查,比如没有from,select拼写错误等。
2,到数据字典里校验SQL语句涉及的对象和列是否都存在,这个过程会加载dictionary cache
3,将对象进行名称转换。比如同名词转换,select * from t其实t是指向hr.t1。
4,看用户是否有访问SQL语句所引用的对象的权限。
5,根据数据字典里记录的对象的统计信息,通过优化器创建一个最优的执行计划,涉及大量数学运算,最消耗CPU。
6,将执行计划,SQL文本等装载进library cache的堆中。
如果在bucket(某种链表)中找到了该SQL语句,则软解析,有三种类型:(越下越高效,其实是去除生成执行计划与权限检验
步骤)
1.当某个session发出的SQL语句与library cache里其他session发出的语句一致,这时去掉硬解析中的5和6.
2.当某个session发出自己之前执行过的SQL语句,去掉2,3,5,6
3.当某个session第三次执行相同的SQL时,则会把SQL语句的游标信息转移到该session的PGA里,以备以后再用时最高
效,但会消耗很大的内存。
*清空shared pool里所有的SQL语句:alter system flush shared_pool;
*导致SQL语句不能共享的因素:SQL本文大小写不一致,SQL语句绑定变量类型不一致,SQL优化器模式不一致。
设置shared pool
10g后已不用操心,有ASSM帮忙。
静态就是表名称,列名等;
动态是字面值;
where name='hsj'的where name是静态部分,hsj是动态部分。静态数量有限,动态变化万千。
静态部分对解析的影响远大于动态部分,对于相同的静态部分的SQL语句,一般执行计划是一样的。
动态部分用绑定变量,就能容易找到相同的SQL语句,效率就高。
shared pool的内存结构
库缓存libarary cache(交换频繁)
数据字典缓存dictionary cache(不太交换)
libarary cache存放了最近执行的SQL语句,存储过程,函数,解析树与执行计划等。
dictionary cache存放在执行SQL语句过程中参考的数据字典的信息,如表名,列名,权限等,数据以数据行存储,而不是数据
块,所以又叫row cache。
shared pool由内存块chunk组成
四种chunk:越向下越难被重用
1.free 空白chunk,可以不受限制地分配
2.recr 有内容的chunk,比如很多共享SQL语句的chunk是recreatable。但可以拿来用,需要再重建。
3.freeabl 处理过程中间产生的,移走的话无法被重建。
4.perm permanent,chunk包含永久对象;
chunk空白时不属于library cache又不属于dictionary cache,再被哪个用就属于哪个。
shared pool中,free类型的chunk串成可用链表(Freelist),如果某个进程发现freelist上的chunk不够用,就从recr链表中释
放掉部分chunk,加入到freelist中。
ORACLE8i之后,为减轻shared pool latch争用问题,大大增加了freelist数量。
当SQL语句进入Library cache时,ORACLE会到dictionary cache中去找与sharedpool_test表有关的数据字典信息,比如表名,列
,用户权限。如果发现没有,则会将system表空间里的数据字典信息调入buffer cache,读取数据块里关于数据字典的内容,再将这些内
容按行的形式放入dictionary cache里。
SQL语句解析过程,硬解析与软解析。一条SQL首次执行时必须硬解析。
当客户端发出一条SQL语句,进入shared pool,Oracle将SQL文本转换成ASCII值,再根据hash函数计算其对应的hash值,再到
library cache中找到相应的bucket,再找出是否存在该SQL语句。
如果不存在,则先获得shared pool latch,然后在freelist中找到可用的chunk,然后这些chunk就认为是进入了library cache
了。接下来是硬解析。
硬解析:1,对SQL语句进行文法检查,比如没有from,select拼写错误等。
2,到数据字典里校验SQL语句涉及的对象和列是否都存在,这个过程会加载dictionary cache
3,将对象进行名称转换。比如同名词转换,select * from t其实t是指向hr.t1。
4,看用户是否有访问SQL语句所引用的对象的权限。
5,根据数据字典里记录的对象的统计信息,通过优化器创建一个最优的执行计划,涉及大量数学运算,最消耗CPU。
6,将执行计划,SQL文本等装载进library cache的堆中。
如果在bucket(某种链表)中找到了该SQL语句,则软解析,有三种类型:(越下越高效,其实是去除生成执行计划与权限检验
步骤)
1.当某个session发出的SQL语句与library cache里其他session发出的语句一致,这时去掉硬解析中的5和6.
2.当某个session发出自己之前执行过的SQL语句,去掉2,3,5,6
3.当某个session第三次执行相同的SQL时,则会把SQL语句的游标信息转移到该session的PGA里,以备以后再用时最高
效,但会消耗很大的内存。
*清空shared pool里所有的SQL语句:alter system flush shared_pool;
*导致SQL语句不能共享的因素:SQL本文大小写不一致,SQL语句绑定变量类型不一致,SQL优化器模式不一致。
设置shared pool
10g后已不用操心,有ASSM帮忙。