CSDN博客

img allun

常用的查看数据库的SQL Oracle经验技巧集

发表于2004/11/2 10:36:00  1564人阅读

Oracle经验技巧集

1.删除表空间

    DROP TABLESPACE TableSpaceName [INCLUDING CONTENTS [AND DATAFILES]]

2.删除用户

    DROP USER User_Name CASCADE

3.删除表的注意事项

    在删除一个表中的全部数据时,须使用TRUNCATE TABLE 表名;因为用DROP TABLEDELETE * FROM 表名时,TABLESPACE表空间该表的占用空间并未释放,反复几次DROPDELETE操作后,该TABLESPACE上百兆的空间就被耗光了。

4having子句的用法

    having子句对group by子句所确定的行组进行控制,having子句条件中只允许涉及常量,聚组函数或group by 子句中的列。

5.外部联接"+"的用法

    外部联接"+"按其在"="的左边或右边分左联接和右联接.若不带"+"运算符的表中的一个行不直接匹配于带"+"预算符的表中的任何行,则前者的行与后者中的一个空行相匹配并被返回.若二者均不带’+,则二者中无法匹配的均被返回.利用外部联接"+",可以替代效率十分低下的 not in 运算,大大提高运行速度.例如,下面这条命令执行起来很慢

 

    用外联接提高表连接的查询速度

    在作表连接(常用于视图)时,常使用以下方法来查询数据:

    SELECT PAY_NO, PROJECT_NAME

    FROM A

    WHERE A.PAY_NO NOT IN (SELECT PAY_

    NO FROM B WHERE VALUE >=120000);

    ---- 但是若表A10000条记录,表B10000条记录,则要用掉30分钟才能查完,主要因为NOT IN要进  行一条一条的比较,共需要10000*10000次比较后,才能得到结果。该用外联接后,可以缩短到1分左右的时间:

    SELECT PAY_NO,PROJECT_NAME

    FROM A,B

    WHERE A.PAY_NO=B.PAY_NO(+)

    AND B.PAY_NO IS NULL

    AND B.VALUE >=12000;

6set transaction命令的用法

    在执行大事务时,有时oracle会报出如下的错误:

    ORA-01555:snapshot too old (rollback segment too small)

  这说明oracle给此事务随机分配的回滚段太小了,这时可以为它指定一个足够大的回滚段,以确保这个事务的成功执行.例如

 

    set transaction use rollback segment roll_abc;

    delete from table_name where ...

    commit;

  回滚段roll_abc被指定给这个delete事务,commit命令则在事务结束之后取消了回滚段的指定
7.数据库重建应注意的问题

 

  在利用import进行数据库重建过程中,有些视图可能会带来问题,因为结构输入的顺序可能造成视图的输入先于它低层次表的输入,这样建立视图就会失败.要解决这一问题,可采取分两步走的方法:首先输入结构,然后输入数据.命令举例如下 (uesrname:jfcl,password:hfjf,host sting:ora1,数据文件:expdata.dmp):

imp jfcl/hfjf@ora1 file=empdata.dmp rows=N

imp jfcl/hfjf@ora1 file=empdata.dmp full=Y buffer=64000

commit=Y ignore=Y

  第一条命令输入所有数据库结构,但无记录.第二次输入结构和数据,64000字节提交一次.ignore=Y选项保证第二次输入既使对象存在的情况下也能成功.

select a.empno from emp a where a.empno not in

 (select empno from emp1 where job=’SALE’);

  倘若利用外部联接,改写命令如下:

select a.empno from emp a ,emp1 b

where a.empno=b.empno(+)

and b.empno is null

and b.job=’SALE’;

  可以发现,运行速度明显提高.

8.从已知表新建另一个表:

CREATE TABLE b

AS SELECT * (可以是表a中的几列)

FROM a

WHERE a.column = ...;

9.查找、删除重复记录:

法一: Group by语句 此查找很快的

select count(num), max(name) from student --查找表中num列重复的,列出重复的记录数,并列出他的name属性

group by num

having count(num) >1 --num分组后找出表中num列重复,即出现次数大于一次

 

delete from student(上面Select)

这样的话就把所有重复的都删除了。-----慎重

 

法二:当表比较大(例如10万条以上),这个方法的效率之差令人无法忍受,需要另想办法:

---- 执行下面SQL语句后就可以显示所有DRAWINGDSNO相同且重复的记录

SELECT * FROM EM5_PIPE_PREFAB

WHERE ROWID!=(SELECT MAX(ROWID) FROM EM5_PIPE_PREFAB D --D相当于First,Second

WHERE EM5_PIPE_PREFAB.DRAWING=D.DRAWING AND

EM5_PIPE_PREFAB.DSNO=D.DSNO);

 

---- 执行下面SQL语句后就可以刪除所有DRAWINGDSNO相同且重复的记录

DELETE FROM EM5_PIPE_PREFAB

WHERE ROWID!=(SELECT MAX(ROWID) FROM EM5_PIPE_PREFAB D

WHERE EM5_PIPE_PREFAB.DRAWING=D.DRAWING AND

EM5_PIPE_PREFAB.DSNO=D.DSNO);

 

10.返回表中[NM]条记录:

 

取得某列中第N大的行

select column_name from

(select table_name.*,dense_rank() over (order by column desc) rank from table_name)

where rank = &N

 

 假如要返回前5条记录:

  select * from tablename where rownum<6;(或是rownum <= 5 或是rownum != 6)

假如要返回第5-9条记录:

select * from tablename

where …

and rownum<10

minus

select * from tablename

where …

and rownum<

order by name

 选出结果后用name排序显示结果。(先选再排序)

 

注意:只能用以上符号(<<=!=)

select * from tablename where rownum != 10;返回的是前9条记录。

不能用:>,>=,=,Between...and。由于rownum是一个总是从1开始的伪列,Oracle 认为这种条件 不成立,查不到记录.

 

另外,这个方法更快:

select * from (

select rownum r,a from yourtable

where rownum <= 20

order by name )

where r > 10

这样取出第11-20条记录!(先选再排序再选)

要先排序再选则须用select嵌套:内层排序外层选。

 

rownum是随着结果集生成的,一旦生成,就不会变化了;同时,生成的结果是依次递加的,没有1就永远不会有2!

rownum 是在 查询集合产生的过程中产生的伪列,并且如果where条件中存在 rownum 条件的话,则:

1: 假如 判定条件是常量,则:

只能 rownum = 1, <= 大于1 的自然数, = 大于1 的数是没有结果的, 大于一个数也是没有结果的

即 当出现一个 rownum 不满足条件的时候则 查询结束   this is stop key!

2: 当判定值不是常量的时候

若条件是 = var , 则只有当 var 1 的时候才满足条件,这个时候不存在 stop key ,必须进行 full scan ,对每个满足其他where条件的数据进行判定

选出一行后才能去选rownum=2的行……

 

 

11.快速编译所有视图

 

---- 当在把数据库倒入到新的服务器上后(数据库重建),需要将视图重新编译一遍,因为该表空间视图到其它表空间的表的连接会出现问题,可以利用PL/SQL的语言特性,快速编译。

SQL >SPOOL ON.SQL

SQL >SELECT ‘ALTER VIEW ‘||TNAME||’

COMPILE;’ FROM TAB;

SQL >SPOOL OFF

然后执行ON.SQL即可。

SQL >@ON.SQL

当然,授权和创建同义词也可以快速进行,如:

SQL >SELECT ‘GRANT SELECT ON ’

||TNAME||’ TO USERNAME;’ FROM TAB;

SQL >SELECT ‘CREATE SYNONYM

||TNAME||’ FOR USERNAME.’||TNAME||’;’ FROM TAB;

 

 

--------------------

让你的天空只有甜和美

 

遗忘———该怎么流泪

 

文章选项:

 

Lunatic

(stranger)

06/13/03 11:33

[精华] Re: Oracle 常用命令 [re: Lunatic]

 

 

 

12.读写文本型操作系统文件

---- PL/SQL 3.3以上的版本中,UTL_FILE包允许用户通过PL/SQL读写操作系统文件。如下:

 

DECALRE

FILE_HANDLE UTL_FILE.FILE_TYPE;

BEGIN

FILE_HANDLE:=UTL_FILE.FOPEN(

C:/’,’TEST.TXT’,’A’);

UTL_FILE.PUT_LINE(FILE_HANDLE,’

HELLO,IT’S A TEST TXT FILE’);

UTL_FILE.FCLOSE(FILE_HANDLE);

END;

 

 

13.在数据库触发器中使用列的新值与旧值

---- 在数据库触发器中几乎总是要使用触发器基表的列值,如果某条语句需要某列修改前的值,使用:OLD就可以了,使用某列修改后的新值,用:NEW就可以了。如:OLD.DEPT_NO,:NEW.DEPT_NO

 

 

14.数据库文件的移动方法

当想将数据库文件移动到另外一个目录下时,可以用ALTER DATABASE命令来移动(ALTER TABLESPACE适用性强)

1. 使用SERVER MANAGER关闭实例.

SVRMGR > connect internal;

SVRMGR > shutdown;

SVRMGR >exit;

2. 使用操作系统命令来移动数据库文件位置(假设这里操作系统为SOLARIS 2.6). UNIX中用 mv命令可以把文件移动到新的位置,

#mv /ora13/orarun/document.dbf /ora12/orarun

3. 装载数据库并用alter database命令来改变数据库中的文件名.

SVRMGR > connect internal;

SVRMGR > startup mount RUN73;

SVRMGR > alter database rename file

> ‘/ ora13/orarun/document.dbf’

> ‘/ ora12/orarun/document.dbf’;

4. 启动实例.

SVRMGR > alter database open;

 

 

15.连接查询结果:

a a1 a2

记录 1 a

1 b

2 x

2 y

2 z

select能选成以下结果:

1 ab

2 xyz

 

下面有两个例子:

1.使用pl/sql代码实现,但要求你组合后的长度不能超出oracle varchar2长度的限制

create or replace type strings_table is table of varchar2(20);

/

create or replace function merge (pv in strings_table) return varchar2

is

ls varchar2(4000);

begin

for i in 1..pv.count loop

ls := ls || pv(i);

end loop;

return ls;

end;

/

create table t (id number,name varchar2(10));

insert into t values(1,'Joan');

insert into t values(1,'Jack');

insert into t values(1,'Tom');

insert into t values(2,'Rose');

insert into t values(2,'Jenny');

 

column names format a80;

select t0.id,merge(cast(multiset(select name from t where t.id = t0.id) as strings_table)) names

from (select distinct id from t) t0;

 

drop type strings_table;

drop function merge;

drop table t;

 

 

2.纯粹用sql

dept, emp

要得到如下结果

deptno, dname, employees

---------------------------------

10, accounting, clark;king;miller

20, research, smith;adams;ford;scott;jones

30, sales, allen;blake;martin;james;turners

每个deptemployee串起来作为一条记录返回

 

This example uses a max of 6, and would need more cut n pasting to do more than that

 

SQL> select deptno, dname, emps

2 from (

3 select d.deptno, d.dname, rtrim(e.ename ||', '||

4 lead(e.ename,1) over (partition by d.deptno

5 order by e.ename) ||', '||

6 lead(e.ename,2) over (partition by d.deptno

7 order by e.ename) ||', '||

8 lead(e.ename,3) over (partition by d.deptno

9 order by e.ename) ||', '||

10 lead(e.ename,4) over (partition by d.deptno

11 order by e.ename) ||', '||

12 lead(e.ename,5) over (partition by d.deptno

13 order by e.ename),', ') emps,

14 row_number () over (partition by d.deptno

15 order by e.ename) x

16 from emp e, dept d

17 where d.deptno = e.deptno

18 )

19 where x = 1

20 /

 

DEPTNO DNAME EMPS

------- ----------- ------------------------------------------

10 ACCOUNTING CLARK, KING, MILLER

20 RESEARCH ADAMS, FORD, JONES, ROONEY, SCOTT, SMITH

30 SALES ALLEN, BLAKE, JAMES, MARTIN, TURNER, WARD

 

 

 

16.在Oracle中建一个编号会自动增加的字段,以利于查询

 

1、建立序列:

CREATE SEQUENCE checkup_no_seq

NOCYCLE

MAXVALUE 9999999999

START WITH 2;

 

2、建立触发器:

CREATE OR REPLACE TRIGGER set_checkup_no

BEFORE INSERT ON checkup_history

FOR EACH ROW

DECLARE

next_checkup_no NUMBER;

BEGIN

--Get the next checkup number from the sequence

SELECT checkup_no_seq.NEXTVAL

INTO next_checkup_no

FROM dual;

 

--use the sequence number as the primary key

--for the record being inserted

:new.checkup_no := next_checkup_no;

END;

 

 

17.查看对象的依赖关系(比如视图与表的引用)

 

查看视图:dba_dependencies 记录了相关的依赖关系

查东西不知道要查看哪个视图时,可以在DBA_Objects里看,

select object_name from dba_objects where object_name like '%ROLE%'(假如查看ROLE相关)

然后DESC一下就大体上知道了。

 

 

18.要找到某月中所有周五的具体日期

select to_char(t.d,'YY-MM-DD') from (

select trunc(sysdate, 'MM')+rownum-1 as d

from dba_objects

where rownum < 32) t

where to_char(t.d, 'MM') = to_char(sysdate, 'MM') --找出当前月份的周五的日期

and trim(to_char(t.d, 'Day')) = '星期五'

--------

03-05-02

03-05-09

03-05-16

03-05-23

03-05-30

 

如果把where to_char(t.d, 'MM') = to_char(sysdate, 'MM')改成sysdate-90,即为查找当前

月份的前三个月中的每周五的日期。



版权声明:CSDN是本Blog托管服务提供商。如本文牵涉版权问题,CSDN不承担相关责任,请版权拥有者直接与文章作者联系解决。

常用的查看数据库的SQL
查看数据库的SQL

1、查看表空间的名称及大小
select t.tablespace_name, round(sum(bytes/(1024*1024)),0) ts_size
from dba_tablespaces t, dba_data_files d
where t.tablespace_name = d.tablespace_name
group by t.tablespace_name;

2、查看表空间物理文件的名称及大小
select tablespace_name, file_id, file_name,
round(bytes/(1024*1024),0) total_space
from dba_data_files
order by tablespace_name;

3、查看回滚段名称及大小
select segment_name, tablespace_name, r.status,
(initial_extent/1024) InitialExtent,(next_extent/1024) NextExtent,
max_extents, v.curext CurExtent
From dba_rollback_segs r, v$rollstat v
Where r.segment_id = v.usn(+)
order by segment_name ;

4、查看控制文件
select name from v$controlfile;

5、查看日志文件
select member from v$logfile;

6、查看表空间的使用情况
select sum(bytes)/(1024*1024) as free_space,tablespace_name
from dba_free_space
group by tablespace_name;
SELECT A.TABLESPACE_NAME,A.BYTES TOTAL,B.BYTES USED, C.BYTES FREE,
(B.BYTES*100)/A.BYTES "% USED",(C.BYTES*100)/A.BYTES "% FREE"
FROM SYS.SM$TS_AVAIL A,SYS.SM$TS_USED B,SYS.SM$TS_FREE C
WHERE A.TABLESPACE_NAME=B.TABLESPACE_NAME AND A.TABLESPACE_NAME=C.TABLESPACE_NAME;

7、查看数据库库对象
select owner, object_type, status, count(*) count# from all_objects group by owner, object_type, status;

8、查看数据库的版本 
Select version FROM Product_component_version
Where SUBSTR(PRODUCT,1,6)='Oracle';

9、查看数据库的创建日期和归档方式
Select Created, Log_Mode, Log_Mode From V$Database;








   存储性能评估

在存储性能评估的时候,我们使用磁盘性能指数(DPI, Disk Performance Index),下表列出了DPI中的各项指数,这个评分系统并不意味着对磁盘的使用和分配的全方位评估,而只是代表一个晴雨表,反映当前磁盘的使用和分配上是否存在需要改进或者注意的地方。

 

MPI指数

分类

所需等级

最高分

调整表和索引

30

表的行连接问题

30

分离关键的Oracle文件

30

回滚段的平衡

 

30

临时段的平衡

 

30

使用最多的前10SQL的磁盘使用率

<5%

60

是否已经调整使用磁盘最多的前25SQL

40

MPI指数

总分

250

 

1. 调整表和索引

由于表和索引的数据块通常是被同时读取的,所以应该尽量将表和其相关联的索引放置在不同的磁盘上,以便减少文件的I/O冲突。

 

检查方法:

select i.index_name, t.table_name, t.tablespace_name
  from user_tables t, user_indexes i
 where t.table_name = i.table_name
   and t.tablespace_name = i.tablespace_name;

 

返回结果是创建在相同表空间中的表和相关联的索引。建议创建新的表空间用于专门存放索引,并将当前的索引rebuild到新创建的表空间中。

alter index idx_name rebuild tablespace ts_name;

评估准则:

等级

分数

表和索引放在同一磁盘上

0

存储使用了磁盘阵列,没有进一步调整

20

存储使用了磁盘阵列,对于RAID类型已经作过调整

30

表和索引已经规划在不同磁盘上

30

 

2. 表的行链接问题

当更新一张表,而数据块中又没有足够的剩余空间来容纳所作的修改时,就会发生行链接现象,该记录被链接到另外一个有足够空间的数据块中,也就是一条记录跨越了多个数据块,这样在读取该记录的时候就会消耗更多的I/O,当数据库中有大量的行链接现象存在时,数据库的整体性能就会下降。

 

检查方法:

sqlplus /nolog

connect app_user/password

SQL> @$ORACLE_HOME/rdbms/admin/utlchain.sql

SQL> analyze table <table_name> list chained rows;

SQL> select count(*) chained_rows, table_name
  from chained_rows
 group by table_name;

 

如果没有返回任何行,则表示没有行链接现象。否则将按照已经分析过的表显示每张表中有多少记录出现了行链接现象。

行链接现象的产生跟PCTFREE参数的设置不当有关系。PCTFREE值默认为10%,如果系统中存在大量行链接,表示这个参数指定的块保留空间过小,不足以容纳块中所有记录的更新操作。此时应该增大相应表的PCTFREE值。

 

评估准则:

等级

分数

存在行链接现象

0

不存在行链接现象

30

 

3. 分离关键的Oracle文件

无论是出于安全性的考虑还是性能的考虑,都建议将关键的Oracle文件分布在可用的独立磁盘上。

首先在错误出现之后,用来被恢复的数据文件和用来恢复的控制文件,重作日志文件,归档日志文件应该分离存放。如果有可能,将下列各个关键文件分布在不同的磁盘上。

系统表空间(SYSTEM),临时表空间(TEMP),回滚表空间(UNDO),联机重作日志文件(REDO)和归档日志文件(ARCH),经常访问的用户表空间,经常访问的用户索引表空间,操作系统盘,$ORACL_EBASE中的关键Oracle软件文件。

至少联机重作日志文件(REDO)和归档日志文件(ARCH)应该跟其它文件存放在不同的磁盘上,并且由于日志文件的大部分时间为只写属性,所以需要考虑RAID5在写方面的弱势,尽量不要将日志文件存放在RAID5的阵列组上。

 

检查方法:

select file_name, tablespace_name, bytes
  from dba_data_files
union all
select file_name, tablespace_name, bytes
  from dba_temp_files
union all
select name file_name, NULL, NULL
  from v$controlfile
union all
select member file_name, to_char(a.group#) tablespace_name, b.bytes bytes
  from v$logfile a, v$log b
 where a.group# = b.group#
union all (select value file_name, NULL, NULL
             from v$parameter
            where name like
'log_archive_dest_%'
              and value is not null
           minus
           select value file_name, NULL, NULL
             from v$parameter
            where name like
'log_archive_dest_state%');

 

返回数据库中所有关键文件存储的位置,由DBASA考察返回的结果,确认已经对于关键文件的存储位置作过符合实际情况的调整。

 

评估准则:

等级

分数

没有调整,全部在单个磁盘上

0

没有调整,全部在RAID

20

已经调整

30

 

4. 回滚段的平衡

Oracle 9iOracle9i之前如果没有使用回滚段自动管理,那么对于回滚段的性能仍然是需要监控并且调整的。

 

检查是否使用了回滚段自动管理:

select name, value from v$parameter where name like '%undo_%';

 

如果返回结果中undo_management的值是AUTO,则表示使用了回滚段自动管理,同时undo_tablespace值显示了自动管理使用的回滚表空间,undo_retention值显示了在回滚表空间中保留回滚数据的时限,以秒为单位。

注意:如果undo_management的值是AUTO但是undo_tablespace没有设置相应的值那么就会使用SYSTEM表空间中的SYSTEM回滚段这个是绝对应该避免的现象。

 

如果没有使用回滚段自动管理,那么需要监控用户使用回滚段的频度,原则上认为不应该有超过1个用户同时使用1个回滚段。

 

检查方法:

select a.name,
       b.extents,
       b.rssize,
       b.xacts,
       b.waits,
       b.gets,
       optsize,
       status
  from v$rollname a, v$rollstat b
 where a.usn = b.usn;

 

检查输出结果,对于所有回滚段而言,如果xacts(活动事务)和waits(段头等待)经常超出1,那么就表明需要增加回滚段数目,以避免可能出现的争用。

增加回滚段的方法:

create rollback segment rs_name tablespace RBS storage(initial 1M next 2M);
alter rollback segment rs_name online;

 

如果使用了回滚段自动管理,那么可以从v$undostat, v$rollstat, dba_undo_extents等视图中查询当前回滚段的使用和分配情况。

 

评估准则:

等级

分数

有回滚段等待现象

0

无回滚段等待现象

30

使用了回滚段自动管理

30

 

5. 临时段的平衡

当初始化参数中定义的SORT_AREA_SIZE大小无法满足排序要求的空间,就会使用临时表空间中的临时段进行排序,磁盘排序比内存排序要慢100-10000倍,所以尽量减少磁盘排序是性能调整工作的一个重要部分。

可能引起排序的操作有create index, distinct, order by, group by等。

 

检查方法:

select name, value from v$sysstat where name like '%sorts%';

 

返回结果中的sorts (memory)表示内存排序,而sorts (disk)则表示磁盘排序,如果存在大量的磁盘排序,则表明我们需要增加SORT_AREA_SIZE或者HASH_AREA_SIZE等排序区的大小,或者需要检查目前系统中消耗大量磁盘的SQL是否已经经过调整(检查前25位消耗磁盘的SQL在后面部分将提到)。

 

检查使用磁盘排序的会话信息,可以定位执行了大量磁盘排序的会话。

检查方法:

select b.name, a.sid, a.value
  from v$sesstat a, v$statname b
 where a.STATISTIC# = b.STATISTIC#
   and b.name =
'sorts (disk)'
   and a.value >
0
 order by a.value desc;

如果有可能我们应该将临时表空间中的多个临时数据文件分布在不同的磁盘上,以减少排序时可能会产生的磁盘冲突。

Oracle9i中,我们可以设置PGA_AGGREGATE_SIZE初始化参数来指定所有会话将使用的PGA大小,同时也必须设置WORKAREA_SIZE_POLICY参数为AUTO。其它详细信息见内存性能评估中4。内存中的排序部分。

 

评估准则:

等级

分数

对于存在的磁盘排序没有评估

0

已经就存在的磁盘排序进行过调整

30

 

6. 最浪费磁盘读操作的前10个语句占所有语句的比例

通常一个没有优化系统中,10个最常用的SQL语句的访问量会占到整个系统中磁盘读操作的50%以上。这些SQL是最需要进行优化的部分,也是优化工作中优先级很高的部分。通常我们的优化目标是将这些SQL的磁盘读操作百分比降低到5-19%

 

检查方法:

select sum(pct_bufgets)
  from (select rank() over(order by disk_reads desc) as rank_bufgets,
               to_char(
100 * ratio_to_report(disk_reads) over(), '999.99') pct_bufgets
          from v$sqlarea)
 where rank_bufgets <
11;

 

评估准则:

等级

分数

<5%

60

5-19%

50

20-25%

30

>25%

0

 

7. 调整前25个最浪费磁盘读操作的语句

在没有调整的情况下,绝大多数系统中,访问量占前25位的语句的磁盘读操作将占用整个系统所有磁盘读操作的75%,对这部分语句进行调整是至关重要的。这部分脚本用于获得访问量占前25位的SQL语句。输出结果中的Exec表示该SQL被执行的次数。

 

检查方法:

set serveroutput on size 1000000
declare
  execution number;
  top25     number;
  text1     varchar2(
4000);
  x         number;
  len1      number;
  cursor c1 is
    select executions, disk_reads, substr(sql_text,
1, 4000)
      from v$sqlarea
     order by disk_reads desc;
begin
  dbms_output.put_line(
'Exec' || '  ' || 'Reads' || '      ' || 'Text');
  dbms_output.put_line(
'-----' || ' ' || '--------' || ' ' ||
                      
'-------------');
  open c1;
  for i in
1 .. 25 loop
    fetch c1
      into execution, top25, text1;
    dbms_output.put_line(rpad(to_char(execution),
5) || ' ' ||
                         rpad(to_char(top25),
8) || ' ' ||
                         substr(text1,
1, 66));
    len1 := length(text1);
    x    :=
66;
    while len1 > x -
1 loop
      dbms_output.put_line(
'-              ' || substr(text1, x, 66));
      x := x +
66;
    end loop;
  end loop;
end;
/

 

评估准则:

本部分没有具体的评估准则,需要开发人员或者DBA去确认在这25SQL中属于应用系统的语句是否都已经作过调优。

 

8. 其它存储相关的调整

1)      字典管理表空间中的Extent总数不超过4096

检查方法:

select a.tablespace_name, sum(a.extents)
  from dba_segments a, dba_tablespaces b
 where a.tablespace_name = b.tablespace_name
   and b.extent_management =
'DICTIONARY'
 group by a.tablespace_name
 order by sum(a.extents);

 

检查输出结果,如果显示某个表空间中的extents总数超过了4096,那么需要扩大这个表空间的extent大小,过多的extent对于DMT的空间管理有负面影响。

 

2)      本地管理表空间中单个SegementExtent数不超过1024

检查方法:

select segment_name, segment_type, extents, bytes, b.tablespace_name
  from dba_segments a, dba_tablespaces b
 where a.tablespace_name = b.tablespace_name
   and b.extent_management =
'LOCAL'
   and a.extents >
1024;

 

检查输出结果,返回的记录都是单个段的区间大于1024的对象,对于这些对象,应该创建一个单独的具有更大extent大小的表空间,然后将这些对象move到新的表空间中去。

 

3)      检查字典管理表空间的PCTINCREASE值是否是0

为了表空间中的所有extent大小相同,建议表空间中的所有段都不要设置独立的storage参数。对于表空间的pctincrease参数,建议设置为0,同时应该设置minextents参数,保证初始分配足够的空间给新创建的对象。

对于LMT表空间,storage参数中的pctincreasenext参数均无效,建议设置适当的uniform参数管理表空间的extent分配。

 

4)      考虑使用分区来避免磁盘争用

分区表在管理的方便性和性能的提高上都有较强的实用性,甚至可以认为分区是提高与大型表有关的性能的最佳方法。通过访问一个表或者索引的较小片段,而不是访问整个表或索引,分区可以很好地提高效率。如果一个表或者索引的分区位于不同的磁盘上,就更可以大大增加数据吞吐量,获得很好的数据库性能。

对于分区的使用,暂时不在本文的叙述范围内,请参阅其它的分区文档。

 

5)      对于分区表的非分区键索引是否是全局分区索引

由于分区表的数据量通常比较巨大,所以如果在分区表的非分区键上创建索引,那么建议创建为全局分区索引,这样能够更好地提高性能。注意:如果截断了一个分区的数据或者删除了一个分区,那么必须rebuild这个分区表中的全部全局索引,否则这些全局索引将处于invalid状态,导致使用到这些索引的SQL语句失败。


数据库性能检查指导方案

 

Author: Kamus

Date2004-9

 

在系统稳定之后,应该按照本指导方案每个月检查一次产品数据库。

该指导方案适用于Oracle9i数据库,因为有些脚本在9i中才可以运行。

检查方式均为以sysdba身份登录数据库以后在SQLPLUS中执行命令脚本(每小节的“检查方法”部分有详细的命令脚本)。

登陆数据库的命令:

sqlplus “sys/password as sysdba”

 

一.内存性能评估

在内存性能评估的时候,我们使用内存性能指数(MPI, Memory Performance Index),下表列出了MPI中的各项指数,这个评分系统并不意味着对内存的使用和分配的全方位评估,而只是代表一个晴雨表,反映当前系统内存的使用和分配状况。

 

MPI指数

分类

所需等级

最高分

缓冲区命中率(Buffer Cache

>98%

30

数据字典命中率(Dictionary Cache

>98%

30

库缓存命中率(Library Cache

>98%

30

内存中的排序(Sort in Memory

>98%

30

空闲的数据缓冲区比例

10-25%

30

使用最多的前10SQL占用的内存

<5%

60

是否已经调整使用最多的前25SQL

30

是否尝试固定高速缓存中经常使用的对象

10

MPI指数

总分

250

 

1. 缓冲区命中率

显示了对于数据总读取量而言,非磁盘读取(缓冲区命中)的百分比。当然,十分高的命中率并不代表数据库性能一定优良,也有可能是糟糕的SQL引起了大量的缓冲区读操作,只有在已经调整过首要的查询之后,这个命中率才能更好地反映数据库性能。

 

检查方法:

select (1 - (sum(decode(name, 'physical reads', value, 0)) /
       (sum(decode(name,
'db block gets', value, 0)) +
       sum(decode(name,
'consistent gets', value, 0))))) * 100
       "Hit Ratio"
  from v$sysstat;

 

评估准则:

等级

分数

<90%

0

90-94%

10

95-98%

20

>98%

30

 

2. 数据字典命中率

显示了对数据字典和其它对象的内存读操作的百分比。

 

检查方法:

select (1 - (sum(getmisses) / sum(gets))) * 100 "Hit Ratio"
  from v$rowcache;

 

评估准则:

等级

分数

<85%

0

86-92%

10

92-98%

20

>98%

30

 

3. 库缓存命中率

显示了对SQLPL/SQL对象的内存读操作的百分比。同样注意,很高的命中率并不总是反映数据库性能优秀。

 

检查方法:

select sum(pins) / (sum(pins) + sum(reloads)) * 100 "Hit Ratio"
  from v$librarycache;

 

评估准则:

等级

分数

<90%

0

90-94%

10

94-98%

20

>98%

30

 

4. 内存中的排序

根据初始化参数PGA_AGGREGATE_TARGET或者SORT_AREA_SIZE的值,用户的排序操作可能在内存中执行,也可能在临时表空间中执行。这个检查用以显示在内存中排序占总排序的百分比。

 

检查方法:

select a.value "Disk Sorts",
       b.value "Memory Sorts",
       round((
100 * b.value) /
             decode((a.value + b.value),
0, 1, (a.value + b.value)),
            
2) "Pct Memory Sorts"
  from v$sysstat a, v$sysstat b
 where a.name =
'sorts (disk)'
   and b.name =
'sorts (memory)';

 

评估准则:

等级

分数

<90%

0

90-94%

10

94-98%

20

>98%

30

 

5. 空闲的数据缓冲区比例

空闲的记录数除以X$BH表中的记录总数(即所分配的数据块缓冲区的总数)得到的空闲缓冲区百分比。同样注意,拥有众多空闲缓冲区的数据库不一定是最佳环境,因为可能是缓冲区设置过大,浪费内存。

 

检查方法:

select decode(state,
             
0,
             
'FREE',
             
1,
              decode(lrba_seq,
0, 'AVAILABLE', 'BEING USED'),
             
3,
             
'BEING USED',
              state) "Block Status",
       count(*)
  from x$bh
 group by decode(state,
                
0,
                
'FREE',
                
1,
                 decode(lrba_seq,
0, 'AVAILABLE', 'BEING USED'),
                
3,
                
'BEING USED',
                 state);

 

评估准则:

等级

分数

<5%

0

5-19%

30

20-25%

20

>25%

0

 

 

6. 最浪费内存的前10个语句占全部内存读取量的比例

通常一个没有优化系统中,10个最常用的SQL语句的访问量会占到整个系统中内存读操作的50%以上。这些SQL是最需要进行优化的部分,也是优化工作中优先级很高的部分。

 

检查方法:

select sum(pct_bufgets)
  from (select rank() over(order by buffer_gets desc) as rank_bufgets,
               to_char(
100 * ratio_to_report(buffer_gets) over(), '999.99') pct_bufgets
          from v$sqlarea)
 where rank_bufgets <
11;

 

评估准则:

等级

分数

<5%

60

5-19%

50

20-25%

30

>25%

0

 

7. 调整前25个最浪费内存的语句

在没有调整的情况下,绝大多数系统中,访问量占前25位的语句的内存读操作将占用整个系统所有内存读操作的75%,对这部分语句进行调整是至关重要的。这部分脚本用于获得访问量占前25位的SQL语句。

 

检查方法:

set serveroutput on size 1000000
declare
  top25 number;
  text1 varchar2(
4000);
  x     number;
  len1  number;
  cursor c1 is
    select buffer_gets, substr(sql_text,
1, 4000)
      from v$sqlarea
     order by buffer_gets desc;
begin
  dbms_output.put_line(
'Gets' || '     ' || 'Text');
  dbms_output.put_line(
'--------' || ' ' || '---------------');
  open c1;
  for i in
1 .. 25 loop
    fetch c1
      into top25, text1;
    dbms_output.put_line(rpad(to_char(top25),
9) || ' ' ||
                         substr(text1,
1, 66));
    len1 := length(text1);
    x    :=
66;
    while len1 > x -
1 loop
      dbms_output.put_line(
'"        ' || substr(text1, x, 66));
      x := x +
66;
    end loop;
  end loop;
end;
/

 

评估准则:

本部分没有评估准则,需要开发人员或者DBA去确认在这25SQL中属于应用系统的语句是否都已经作过调优。

 

8. 固定缓存对象

尝试在内存中固定(pin)经常使用的对象,包括表,存储过程等。

检索需要在共享池中要求大于100K连续空间的对象:

select *
  from v$db_object_cache
 where sharable_mem >
100000
   and type in (
'PACKAGE', 'PACKAGE BODY', 'PROCEDURE', 'FUNCTION');

 

考察返回的结果,确认是否需要pin到共享池中,返回结果中的KEPT字段如果是YES,那么表示该对象已经固定在了共享池中,为NO,则表示还没有固定。

如果需要固定,使用下面的语句:

exec dbms_shared_pool.keep('SYS.STANDARD');            

 

数据库默认安装的时候没有创建dbms_shared_pool包,所以需要先创建该包。

cd $ORACLE_HOME/rdbms/admin

sqlplus “/ as sysdba”

@dbmspool.sql

 

如果我们要固定表,那么可以在创建表的时候或者修改表属性时使用CACHE关键字,将表放置到Buffer CacheLRU列表的MRU端。通常我们需要对于较小的但是频繁使用的表进行这种操作。

alter table table_name cache;

我们也可以将需要频繁使用的表放置到另外一个独立的Buffer Cache中,比如KEEP池。这种操作可以使这些表的数据不至于很快被清除出Default Buffer Cache

alter table table_name storage (buffer pool keep);

 

评估准则:

本部分没有评估准则,需要开发人员或者DBA在系统分析以后谨慎执行。

 

二.存储性能评估

三.Statspack报表中需要首先查看的十项内容

 

 

本文参考:

Oracle9i Performance Tuning Tips & Techniques - Richard J.Niemiec

Oracle9i Database Concepts - tahiti.oracle.com

Oracle9i Database Reference - tahiti.oracle.com

 



版权声明:CSDN是本Blog托管服务提供商。如本文牵涉版权问题,CSDN不承担相关责任,请版权拥有者直接与文章作者联系解决。

发表于 2004年09月30日 2:38 AM


评论

# 回复:数据库性能检查指导方案 - Part I 2004-09-30 3:34 AM 5415
看不懂。。。。

# 回复:数据库性能检查指导方案 - Part I 2004-09-30 11:14 AM adam
受教

# 回复:数据库性能检查指导方案 - Part I 2004-10-03 5:14 PM mudfei
期待Part II

# 回复:数据库性能检查指导方案 - Part I 2004-10-08 8:30 PM Fenng
还是基本用比率 (ratio) 来衡量性能

Lewis新介绍了一种方法,不失为一种不错的思路
阅读全文
0 0

相关文章推荐

img
取 消
img