欢迎使用CSDN-markdown编辑器

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(getsgetmissesusagefixed))/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;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值