1.数据类型
char varchar2 number number(m,n) m长度 n精度
date 长度为7:世纪,年,月,日,时,分,秒
timestamp用于存储年,月,日,以及时间的小时,分,秒 其中秒值精确到小数点后6位,该类型包含时区信息
clob 大字符串 可变长 最多4gb的数据 blob 大二进制类型 视频 音频<=4gb
还有几个常用的数据类型 一般是在sql程序中使用
表.列%type 指的是某个表指定列的数据类型;
表%rowtype 指这个表的一行所有列的数据类型;
还有记录类型,表格类型 游标类型 等等等 后面的笔记会涉及 在pl/sql程序中;
2.基本的sql语句
创建表:create table 名字(字段,,约束); 表重命名:rename newName to oldName;
约束:primary key ,check,union,not null,foreign key;
建表添加约束:constraint 约束名 约束类型(foreign key(列名)/check) 对应的约束;
建表后添加约束:alter table 表 add constraint 约束名 列名 约束类型 对应的约束
添加列:alter table 表名 add 列名 数据类型;
修改列:alter table 表 modify 列名 类型;
删除列:alter table 表 drop column 列名;
插入: insert into 表(字段1,字段2…) values(值1,值2….) 和sqlserver mysql 一样
删除:delete [from] 表 where 条件;
另一个摧毁重建表: truncate 表;[后面会有delete 和 truncate的区别]
改表数据:update 表 set 字段=值 f where 条件 ;
查询: 基本的查询类似mysql
分页查询: select * from (select rownum,字段 from 表 where rownum<=?) r where r.rownum>?;
rownum:虚列 查询出来之后排序号(按自然排序下分配;) rownum是查询出后才分配 所以 rownum 不能直接用> 或者>=;
左外连接:
select * from 表1 left join 表 2 on 条件; 等同于:
select * from 表1 ,表2 where 表1.xx=表2.xx(+);带(+)的是匹配表 另一边为基本表 哪边没有(+)就是哪边的方向(左右)外连接;
右外连接 类比左外连接;
全外连接: select * from A full join B on 条件 ; (注意全外不能用(+));
自连接: 单表 自己连接自己(起别名) 不适用于大表 ;
select level,empno,ename,mgr from emp connect by prior empno=mgr start with empno=7566;
上面这条语句是查询员工是下一层员工的领导 这是一个层次查询 这里面的 level是一个伪列,与connect by一起使用 :层次查询 里面的prior 是一个关键词 指上一层.
子查询:也称作为内查询:
注意点:可以在where,select,having,from后面使用子查询,
不能在group by后面使用子查询, 尽量使用多表查询,
这里注意一下相关子查询.以及子查询中的null值:
单行子查询中的null:如果子查询返回null 则主查询的where 一直不等,
多行子查询中的null:
not in 后面不能有null因为 not in (a,b,null) 相当于 xx!=a and xx!bb and xx!=null 永为false ;
in后面可以有null 因为 in 相当于or------or------
消除查询结果中的重复项:distinct : select distinct…….
连接符 可以用 || 也可以用 concat ‘a’||’b’ concat(‘a’,’b’) 连接两个字符串;
3.过滤和排序
过滤:用到where +条件 将不满住的条件过滤;
注意点: 条件中的字符大小写敏感, 日期格式敏感 Oracle中默认的日期格式为:DD-MON-RR 天-月-年;
使用的比较运算符: = 等于 (赋值用 :=) >大于 <小于 <>不等于 (也可以用!==)
between...and
模糊查询 like %xx% 或者like _xxx;
sql的优化:where 解析的顺序 从右到左,尽量把为假的条件放在右边(右边为假 左边不再判断.)
排序:使用order by 列/表达式/别名/序号rownum(select后必须有这个) asc|desc;
如果是null值,正常情况下 null值在上面 有值得在null后 再降序排列;
函数
1.单行函数:
1.字符函数:
LOWER 转小写,
UPPER 转大写,
INITCAP 首字符大写,
拼接 || 或者 concat,
substr(a,1,3) 截取 从a 1 的位置 截取3 个第三个参数不写就是截a的最后;
length/lengthb 长度,
instr(a,b)在a中查找b的位置(索引) 找不到返回0 找到返回位置,
lpad|rpad 左填充 右填充 xx(a,b,c) b是填充后的长度,用c左/右填充a;
trim(a,b) 去掉b中左右的a; 去除前后指定的字符;
replace(a,b,c) 用c替换a中的b;
2.数字函数;
round(a,b)四舍五入 对a四舍五入保留b为小数;
trunc(a,b) 把a中的 后b位截取掉;
3.日期函数:
to_char(日期,’格式’) 把日期以指定的格式输出;例如 yyyy-mm-dd hh24:mi:ss;
months_between(a,b) 日期a,b之间相差的月数;
last_day(日期) 日期所在月的最后一天;
next_day :下一个星期几的日期(从指定日期开始);
round 对日期进行四舍五入;
4.转换函数:
number>>character : to_char 反向:to_number;
char>>date :to_date 反向:to_char;
5.通用函数
vvl(a,b) a不为null 返回a 否则返回b;
nvl2(a,b,c) a不为空 返回b 否则 返回c;
nullif(a,b) a=b时 返回null 否则 返回b;
coalesce(a1,a2,a3…an) 从左到右找到第一个部位null的值并返回;
条件表达式:if—–then—-else:
1.case 表达式:sql99的语法 类似basic 比较繁琐:
case ..(这个地方一般是列名). when xxx then
else…
end
2.decode函数 Oracle自己的语法 类似java:
decode(列名|表达式,条件1,结果1,条件2,结果2…….)
多行函数:
这里的多行函数就是sqlserver mysql中的聚合函数 :avg,sum,count,max,min,
还有分组函数 group by ;;
注意where 后面不能使用多行函数 having后面可以;;
有一个叫做group by的增强语句 rollup 这里就自己百度吧;
sql优化:尽可能少的使用where
创建序列:
create sequence 序列名
start with n,—-从n开始;
increment by m,–每次增长m;
后面还有几个参数 基本不用 就不写了;
使用序列: 下一个序列号 (一般插入时使用 主键) 序列名.nextval;
当前序列:序列名.currval;这里注意开始之前 序列的指针在第一个序列的前;
创建表空间 (必须要有dba权限):
create tablespace 空间名
datafile:'D/XX/XX.DBF'---路径 以.dbf结尾;
size:100m;---大小
删除表空间:drop tablespace 空间名 [including contents and datafiles]
用户授权: grant 权限(角色名)1, 权限(角色名)2……to 用户名;
删除权限:remove 权限名 from 用户名;
创建用户:
create user 用户名
identified by 密码
default tablespace 空间名(不分配就用system的);
删除用户:drop 用户名 cascade;(强制删除)
回滚:
设置保留点: savepoint A(名字) >>rollback to savepoint ;回滚到保存点;
如果没有保留点,就回滚到能回滚到的地方
Oracle中有3种事务隔离级别: read commit 读已提交(默认) serializable 串行化 read only 只读;
数据库对象
一共有10个 可能没有总结全 不重要的没总结;
#对象1: …….上面介绍的全是
对象2:视图 ##
视图是一种虚表,建立在已有的表基础上
语法: create or replace view 名字 as 子查询
[with read only]–只读
[with check option]–通过视图只能插入与视图中一类的数据(比如视图中是部门10的员工,那通过视图只能添加部门10的员工到表中;)
不建议通过视图进行表的修改(一般视图 with read only)
删除视图: drop view 名字;
对象3:序列………………….
对象4:索引 ##
索引就相当于一个目录,通过指针加速Oracle服务器的查询速度..
创建索引:
create or replace index 索引名 on 表(列);
Oracle内部生成索引表(目录) rowid(行地址 伪列) oracle自动维护;
注意:表越大 索引才有意义;
Oracle中的索引类型分为: B树索引(默认的) 位置索引(矩阵)
对象5:同义词
说白了 同义词就是别名;;
create [public] synonym 别名 for 对象;
PL/SQL程序
PL/SQL是什么?pl/sql全程是Procedure Language/SQL 是Oracle对sql的过程化扩展,指在SQL命令语言中增加了过程处理语句(如分支,循环等),使SQL语言具有过程处理能力.PL/SQL是面向过程的语言..还有一种重要的面向过程的语言 叫做Scala基于java.因为在大数据中的两个核心框架 一个是hadoop 基于java 一个是spark 基于scala; 现在的开发 使用的是 SpringMVC+pl/sql 效率高 速度快
declare
--说明部分
begin
--程序
dbms_output.put_line(‘Hello World’); -- 注意句末要有分号 这里的 dbms_output叫做程序包 put_line叫做存储函数
exception
--例外处理语句
end;--注意这地方一定要有分号;
说明部分:
说明变量:基本数据类型:char,varchar2,date,number,boolean,long
引用型变量:表明.列名字%type 和引用到的列的类型相同.
例如:
declare
pename emp.ename%type;
begin
select ename into pename from emp where enpno=7839;
--格式 select 列名1,列名2 into 变量1,变量2 from........ 变量与列一一对应 用 into进行赋值
dbms_output.put_line(pename);
end;
记录型变量 表名%rowtype 一个数组数组中的每个元素就是每一行的每一列
例如:--查询并打印7839的姓名 和薪水
declare
emp_rec emp%rowtype;
begin
select * into emp_rec from emp where empno=7839;
dbms_output.put_line(emp_rec.ename | emp_rec.sal);--变量名.列名
end;
注意:在命令窗口中 输出开关默认为关的 这里要打开 set serveroutput on;
——IF语句
1. IF条件 THEN 语句1; 2.IF条件 THEN 语句序列1 3.IF条件 THEN 语句;
语句2; ELSE 语句序列2; ELSIF 语句 THEN 语句;
END IF; END IF; ELSE 语句;
END IF;
PLSQL程序中 接受从键盘输入:
写在程序的前端
--这里的num:地址值,在该地址上保存了输入的值 输入的都是字符串
accept num prompt '请输入一个数字';
declare
--定义变量保存数字
pnum number := &num --这里的:=就是赋值
begin --开始判断
if pnum=0 then dbms_output.put_line('您输入的是0');
elsif pnum=1 then dbms_output.put_line('您输入的是1');
....
end if;
end;
注意这里面可能在pl/sql应用程序中执行可能会有问题 在命令行中是可以的
—-循环语句—
1.while total<=25000--条件
loop
....
total:=total+salary;
end loop; --条件不成立时 跳出循环
2.loop
exit[when 条件];
...
end loop; --条件成立时 跳出循环;
3. for i in 1..3---1..100这里表示1到100连续的 连续的时候才能用
loop
语句序列;
end loop;
游标Cursor
语法:CURSOR 游标名字[(参数名 数据类型,参数名 数据类型,)] IS SELECT 语句;
例如:cursor c1 is select from emp;
游标的使用步骤:
>>打开游标:open c1;(打开游标执行查询)
>>取一行游标的值: fetch c1 into pjob;(取一行到变量中)
>>关闭游标: close c1;(关闭游标释放资源)
>>游标的结束方式 exit when c1%notfound
>>>>注意上面的pjob必须与emp表中的job列类型一致 定义:pjob emp.job%type;
光标的初始位置在结果的第一行;
/*
光标的属性:
%isopen
%rowcount (影响的行数 比如光标中100行取走10行 则%rowcount是10行)
%found 取到true 取不到false
%notfound
*/
例1:
declare
--定义光标
cursor cemp is select * from emp;
p emp%rowtype;
begin
--打开光标
open cemp;
loop
--取当前记录
fetch cemp into p;
-- 没有取到记录 没有取到记录的时候推出光标
exit when cemp%notfound;
dbms_output.put_line(p.ename||'的薪水是'||p.sal);
end loop;
--关闭光标
close cemp;
end; #
例2:
declare
cursor cemp is select * from emp;
p emp%rowtype;
begin
open cemp;
loop
fetch cemp into p;
if p.job='PRESIDENT' then update emp set sal=sal+1000 where empno=p.empno;
elsif p.job='MANAGER' then update emp set sal=sal+800 where empno=p.empno;
else update emp set sal=sal+400 where empno=p.empno;
end if;
exit when cemp%notfound;
end loop;
close cemp;
--提交ACID (隔离级别) :读已提交
commit;
dbms_output.put_line('完成了');
end; #
带参数的光标:
定义的时候:
cursor cemp(dno number) is select ename from emp where deptno=dno;
打开光标的时候(传入参数)
open cemp(10);;;
异常 用户自定义的例外 ,系统定义的例外:#
系统定义的例外:
No_data_found 没有找到数据
too_many_rows select...into语句匹配多个行
zero_divide 被0除
value_error 算数或转换错误
timeout_on_resource 在等待资源时发生超时 (分布式数据库)
分布式数据库:数据物理上被存放在网络的多个节点上,逻辑上是一个整体;
分布操作:跨节点数据的创建以及查询,跨节点数据更新
当两个节点通讯室,一个节点无法接收到另外一个节点的消息(比如网线断了) 这个时候就会有timeout_on_resource例外
declare
pnum number;
begin
pnum:=1/0;
exception
when zero_divide then dbms_output.put_line('0不能作为坟墓');
when..........
when others then dbms_output.put_line('其他例外');--这里表示其他例外 用when others then...一点要有 处理所有的例外
end;
#
自定义的例外
当做变量进行使用 关键字 raise
declare
v_job char(10);
v_sal emp.sal%type;
no_data exception;--自定义例外 当做变量 没数据例外
cursor c1 is select distinct job from emp order by job;
begin
open c1--开启光标
fetch c1 into v_job
if c1%notfound then raise no_data;--找不到数据就抛这个例外
--pmon进程 用户进程执行失败的时候 清除缓存 清除垃圾 所以西面的 关闭光标(close c1 还是会启动的)
end if;
...
close c1;
exception
with no_data then insert into emp values('fetch语句没有获得数据或者数据已处理完');--把最后的结果保留在表中 下一节讲解
end;
通过几个例题学会pl/sql程序的书写
问题:到底该怎么写呢? 得一鱼 不如得一渔.
首先想清楚:
sql语句:
变量:1.初始值,2.最终得到..
例题1 ##: 统计每年入职的员工个数:
需要的sql: select to_char(hiredate,'yyyy') from emp;
>>>光标>>>循环>>退出条件:notfound
变量: count number :=0 ;
declare
--入职年份
cursor emp_date is select to_char(hiredate,'yyyy')from emp;
phiredate varchar2(4);--获取的入职年份的变量
--计数变量
count87 number :=0;
count80 number :=0;
count82 number :=0;
count81 number :=0;
begin
--开启光标
open emp_date;
loop
fetch emp_date into phiredate;--取一组光标的值 也就是一个员工的入职年份
--判断
exit when emp_date%notfound;
if phiredate='1980' then count80 :=count80+1;
elsif phiredate='1981' then count81 :=count81+1;
elsif phiredate='1982' then count82 :=count82+1;
else count87 :=count87+1;
end if;
end loop;
--关闭光标
close emp_date;
--输出
dbms_output.put_line('Total '||'1980 '||'1981 '||'1982 '||'1987 ');
dbms_output.put_line('==================================================');
dbms_output.put_line(count80+count81+count82+count87||' '||count80||''||count81||''||count82||' '||count87);
end;
例题2 为员工涨工资
从最低工资调起没人长10%,但工资总额不能超过5万元,请计算长工资的人数和涨工资后的工资总额,病输出长工资人数以及工资总额
分析:sql:select ename,sal from emp order by sal;–从最低工资涨起,,
要涨工资的人>>集合>>光标>>>循环>>退出条件:1 总额>5w 2.notfount
变量: 涨工工资的人数 countEmp number :=0; 涨工资之后+1;
涨后的工资总额 salTotal number;
1.select sum(sal) into salTotal from emp;
2.涨后=涨前+sal*0.1;
原则:能不操作数据库就不操作数据库
-- Created on 2017/10/31 by USER
declare
--定义光标
cursor cdep is select empno from emp order by sal;
--说明变量
pempno emp.empno%type;
--涨工资的人数
totalcount number;
--涨后的工资总额
subsal number;
begin
open cdep;--开启光标
loop
--跳出循环的条件 1.总工资>5w
exit when subsal>50000;
--跳出循环的条件 2.notfound
fetch cdep into pempno;
exit when cdep%notfound;
--更新
update emp set sal=round(sal*1.1) where empno=pempno;
select sum(sal) into subsal from emp;
end loop;
close cdep;
--提交事务之前要判断总金额 如果总金额<5w 就提交 否则回滚
if subsal>50000 then rollback;
else commit;
end if;
end;
一层一层地分析 一层一层工地做 这叫做瀑布模型 其他 还有 V模型 螺旋模型等
课下有时间去学习 软件工程 这门课程
例题3 #:
用PL/SQL 语言编写一程序,实现按部门分段(6000以上,(6000,3000),3000以下)统计各个工资断的职工人数,以及各部门的工资总额(工资总额中不包括奖金);
分析sql:select deptno from dept;–要知道都有哪些部门;
select sal from emp where deptno=?? –查询具体部门下的员工工资
分析变量: pdeptno emp.deptno%type;–某个员工所属的部门编号;
psal emp.sal%type;–某个员工的工资
–结果是个表格 这里创建这个表格
create table result_number(
dno number,
num1 number,
num2 number,
num3 number,
subtotal,number
)
declare
--定义光标查询所有部门
cursor cdep is select deptno from dept;
--说明变量
pdeptno dept.deptno%type;--某个员工所属的部门编号;
--定义光标 查询具体部门员工的工资
cursor cdmp(dno number) is select sal from emp where deptno=dno;
psal emp.sal%type;--某个员工的工资
--计数变量
num_1 number;
num_2 number;
num_3 number;
subtotal number;
begin
--开启光标
open cdep;
loop
fetch cdep into pdeptno;--取值
exit when cdep%notfound;
--取到值就 循环部门 获取每个部门下的员工工资
--初始化
num_1 :=0;
num_2 :=0;
num_3 :=0;
subtotal :=0;
open cdmp(pdeptno);
loop
fetch cdmp into psal;
exit when cdmp%notfound;
--如果可以找到值 就判断
if psal<3000 then num_1 :=num_1+1;
elsif psal>3000 then num_3:=num_3+1;
else num_2:=num_2+1;
end if;
end loop;
close cdmp;
insert into result_number values(num_1,num_2,num_3,subtotal )
end loop;
close cdep;
commit;
end;
# 存储过程和存储函数 #
过程和函数中的in 和out #:
一般来讲,过程和函数的区别在于函数可以有一个返回值 而过程没有
但过程和函数都可以通过out指定一个或多个输出参数.我们可以利用out参数,在过程和函数中实现返回多个值.(原则:一般来说实现返回多个值得时候用存储过程,只有一个返回值 那就用存储函数了).
例如:查询某个员工的 姓名 月薪 职位
create or replace procedure queryEmp(eno in number,
pename out varchar2,
psal out number,
pjob out varchar2)
as
begin
select ename,sal,job into pename,psal,pjob from emp where empno=eno;
end;
调用:
begin
queryemp(eno => 7839,
pename => :pename,
psal => :psal,
pjob => :pjob);
end;
Oracle中为什么还要保留存储函数呢
因为版本升级的过程中 要做到向下兼容.兼容以前的版本(以前的版本中有的还没有存储过程,所以要保留存储函数);
可是如果有很多个out参数呢??
例题:查询某个部门中的所有员工信息:>>>>>返回一个集合;
java调用存储过程或者存储函数:
在java中将一个对象置为空 垃圾回收站 会自动回收 gc;
问题:java中的gc 垃圾回收,由jvm来做,,那么我们能不能写代码影响java的垃圾回收呢?
答案: 不能,我们不能通过写代码影响垃圾回收gc,java的垃圾回收不受java代码控制.
运行java程序 在命令窗口中:java -Xms100M -Xmx200M HelloWorld,
意思是运行这个HelloWorld需要的最小堆内存100M,最大堆内存200M,这两个参数直接影响java的垃圾回收的虚拟参数,垃圾回收耗费资源,耗费cpu,所以我们不能经常使用垃圾回收,通过设置这两个参数来影响垃圾回收. 当空余内存不满足所要的操作,才进行垃圾回收.
以后搞计数发展:
技术方向:1.性能优化 2.故障诊断 比如:死锁 ThreadDump ,
查看api
包结构
包头:: 负责声明
申明包结构:
create or replace package mypackage(名字) as
type empcursor(变量类型的名字) is ref cursor;---定义类型 引用光标(自定义的类型)
produce queryEmpList(dno in number,empList out emocursor)--两个参数一个是输入 --一个是输出 输出的是自定义类型(相当于集合)
--这个地方的存储过程/函数 的plsql程序 在包体中进行写;
end mypackage;
创建包体:
create or replace package body mypackage(包的名字) as
produce queryEmpList(dno in number,empList out emocursor) as
-在这个as 后面可以说明变量
begin
open empList for select * from emp where deptno=dno; --注意这里开启光标用的for
end queryEmpList;
end mypackage;
触发器
数据库触发器是一个与表相关联的,存储的PL/SQL.每当一个特定的数据库操作语句(insert update delete) 在指定的表上发出时,Oracle自动地执行触发器中定义的语句序列.
触发器的类型:
语句级触发器:在指定的操作语句操作之前或之后执行一次 不管这条语句影响了多少行.针对表;
行级触发器(FOR EACH ROW):触发语句作用的每一条记录都被触发.在行级触发器中使用 :old和 :new 伪记录变量,识别值得状态.针对行;
创建触发器
create or replace trigger 触发器名字
before/after
delete/insert/update[of 列名] --update可指定列
on 表明
[for each row [when(条件)]] --这是触发器的类型 类型 上面有; 有这一行的时候是行级触发器;没 --没有就是 语句级触发器
plsql子程序块
loqiuhmxwjntbchf
–第一个最简单的触发器:
create or replace trigger abcd --create or replace trigger 名字
after insert --after/befor insert/update/delete 在执行sql之前触发触 --发器还是之后触发.
on emp --on 表 指明触发器关联哪个表;
declare
begin
DBMS_OUTPUT.PUT_LINE("成功插入新员工");
end;
--然后在emp执行insert的后 会触发这个触发器 自动打印"成功插入新员工"
–触发器的应用一:
/*触发器的应用一:禁止在非工作时间插入新员工
1.周末: to_char(sysdate,'day') in("星期六","星期日");
2.上班强,上班后,to_number(to_char(sysdate,'hhh24')) not between 9 and 17 这是9点到18点为工作时间;
这是一个语句级的触发器 */
create or replace trigger securityemp
before insert
on emp
--不需要变量可以不用写declare
begin
--在这里面进行判断
if to_char(sysdate,'day') in('星期六','星期日') or to_number(to_char(sysdate,'hh24')) not between 9 and 17 then
--禁止insert 抛出例外 程序不再往下执行 并打印错误信息
raise_application_error(-20001,'禁止在非工作时间插入新员工'); --第一个参数是错误代码 取值范围-20000~-20999
end if;
end;
--执行插入的时候就会触发这个触发器 进行时间的判断
insert into emp(empno,ename,sal,deptno) values(1004,'fsd',4000,10);
–触发器的应用二:
触发器可用于:
数据确认,实施复杂的安全性检查,做审计 跟踪表上所做的数据操作等(Oracle有它自己的审计 非常强大 下去要找资料自己看),,数据的备份
让Oracle的性能更优秀
SGA主要由三个部分组成,分别是共享池、数据缓冲区、日志缓冲区。
共享池(Share Pool):用于缓存最近被执行的SQL语句和最近被使用的数据定义,主要包括库缓存和数据字典缓冲区。
库缓存主要用来存放用户SQL命令,
数据字典缓冲区用于存放数据库允许的动态信息。
数据缓冲区(Database Buffer Cache):用于缓存从数据文件中检索出来的数据块,可以大大提高查询和更新数据的性能。
日志缓冲区(Log Buffer):为了提高日志文件的操做效率,Oracle数据库会在日志缓冲区中先记录日志,之后在特定的时间点,后台进程会批量写入到日志文件中
1. 对库高速缓存的调整
检查、调整库高速缓存可以通过动态性能视图V$LIBRARYCACHE,查询实例启动后所有库高速缓存的活动
–查看库高速缓存在执行过程中的命中数
select sum(pins) “请求数” ,sum(reloads) “不命中数” from v$librarycache;
–查看库高速缓存的命中率
select (sum(pins-reloads))/sum(pins) “命中率” from v$librarycache;
pins:用于显示在库高速缓存中执行的次数或者请求数;
reloads:用于显示在执行阶段库高速缓存不命中的次数;
1.如果该比率接近0的时候,则应当立即采取措施减少不命中数。措施包括以下两种。
增加初始化参数shared_pool_size的值,提高库高速缓存可用的内存数量,同时为了取得好的效果,还需要增加初始化参数open_cursors的值,用以提高会话允许的游标数目。
通过编写等价的SQL语句,尽可能让SQL语句和PL/SQL语句块可以共享一个SQL区,这样可以减少库高速缓存的不命中数。SQL语句或者PL/SQL语句块文本中的每一个字符都必须要等价,包括大小写和空格。
2 .对数据字典缓存的调整
应用程序已经开始运行,同时数据库处于一种相对稳定状态之后,就可以借助动态性能视图V$ROWCACHE来检查、调整数据字典高速缓存的活动
–查看数据字典缓存不命中数
select sum(gets) “请求数” , sum(getmisses) “不命中数” from v
rowcache;–查看数据字典缓存的使用效率select(sum(gets−getmisses−usage−fixed))/sum(gets)“数据字典使用率”fromv
rowcache;
gets 用于显示数据字典请求总数;
getmisses 用于显示不命中的请求数
usage 用于显示有效数据的缓存项数目
fixed 用于显示固定的缓存项数目
3.调整shared_pool_size的值
分析高速缓存和数据字典缓存的命中率
根据命中率确定是否需要调整shared_pool_size的值
调整方式
show parameter shared_pool_size;
alter system set shared_pool_size=100M SCOPE=SPFILE;
show parmeter open_cursors;
alter system set open_cursors=500;