常用的查看數據庫的SQL Oracle經驗技巧集

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新介紹了一種方法,不失爲一種不錯的思路
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章