簡單點判斷的話,你top或topas觀察下,cpu和磁盤讀的負載情況。
創新互聯建站專注于遷安企業網站建設,成都響應式網站建設公司,商城建設。遷安網站建設公司,為遷安等地區提供建站服務。全流程定制網站,專業設計,全程項目跟蹤,創新互聯建站專業和態度為您提供的服務
然后生成一份業務高峰時段的AWR報告,看看top 5等待事件主要是哪些,是不是跟磁盤讀相關的等待事件(比如全表掃描)
降低IO最有效的方法就是優化sql語句,避免大表全表掃描,根據awr報告中sga各個內存組件的使用情況,適當調整buffer cache的值,來減少磁盤IO
查詢優化器參數
1. optimizer_mode
查詢優化器是為了找一個最高效的執行計劃,這個參數用來定義什么是“高效”,比如是更快還是占用資源更少。在oracle10g中只支持兩個參數值:
all_rows:提供全部數據
first_rows(n):n為大于0的自然數,表示盡快傳輸前面n條數據(比如分頁查詢的時候,我第一次只查詢前面10條數據)
oracle10g默認為all_rows,可以再數據庫級別,會話級別,或者執行SQL的時候修改該參數的值。
數據庫級別:alter system set optimizer_mode=first_rows(10) scope=spfile;
會話級別:ALTER SESSION SET OPTIMIZER_MODE=first_rows(10);
SQL級別:SELECT /*+ first_rows(10) */ id,name from t1 order by id;
其實,默認all_rows是最好的方式,如果確實是只要查詢小部分數據,可以在sql級別加上提示,看是否能提高性能。
2. db_file_multiblock_read_count
在多塊讀的情況下(比如全表掃描),該參數說明一次最多可讀取的數據塊數目。設置得太小的話,效率低。設置得太高也不見得就好(太高,會受I/O最大吞吐量限制。比如設置成一次最多讀取1024塊,但I/O最大吞吐量只允許32塊,那一次最多也只讀取32塊。而且一次讀取很多塊,開銷會偏高。)應該通過測試,才能知道應該把該參數設置成哪一個值。
測試過程:
1. 創建一張大表,比如上千萬行級別的數據
2. 循環設置該參數的值,查看全表掃描的速度。類似于以下語句:
[sql] view plain copy
span style="font-size:14px;" declare
l_count pls_integer;
l_time pls_integer;
l_starting_time pls_integer;
l_ending_time pls_integer;
begin
dbms_output.put_line('dbfmbrc seconds');
for l_dbfmbrc in 1..32
loop
execute immediate 'alter session set db_file_multiblock_read_count='||l_dbfmbrc;
l_starting_time := dbms_utility.get_time();
select /*+ full(t) */ count(*) into l_count from big_table t;
l_ending_time := dbms_utility.get_time();
l_time := round((l_ending_time-l_starting_time)/100);
dbms_output.put_line(l_dbfmbrc||' '||l_time);
end loop;
end;
//span
3. optimizer_index_cost_adj
影響走索引掃描的開銷計算。 取值范圍1到10000.默認值為100,超過100后,走索引掃描的開銷越高,從而使得查詢優化器更加傾向于使用全表掃描。相反,小于100,索引掃描的開銷就越低,從而使得查詢優化器更加傾向于使用索引掃描。從下面索引掃描開銷計算公式可以看出:
io_cost=(blevel+(leaf_blocks+culstering_factor)*selectivity) *optimizer_index_cost_adj/100.
一般是默認值不需要修改,但是如果發現本應該走索引掃描結果走了全表掃描,可以適當調低該值,但是,這個值不應該設置過低,因為,過低的話,如果兩個索引掃描的開銷不同,可能通過該公式一算,開銷就變成一樣的了。總之,不建議修改該參數的值。
PGA參數
1. workarea_size_policy
管理工作區域內存(PGA)的方式,
auto:oracle10g默認方式,委托給內存管理器自動管理(建議不需要修改)
manual:oracle9i默認方式,oracle9i沒有自動管理功能。
2. pga_aggregate_target
如果是自動管理PGA,那么該參數用于指定實例可用的PGA的大小,默認是SGA的20%。即使今后用的內存超過了設置的值,也沒有關系,oracle會自動增大PGA的值。比如該參數設置的是200M,今后某一時刻,需要300M,也是沒問題的,會自動增長。
3. sort_area_size
手動管理PGA,該參數指定分配多大的內存用于排序操作,過小的話,會影響性能,過大的話浪費空間。很難說一個合適的默認值,因為用戶場景變化非常大,實際情況得實際處理。
4. hash_area_size
手動管理PGA,該參數用于指定哈希連接的工作區域大小,同樣建議它的值也很困難。如果過小,那么查詢優化器就會高估哈希連接的開銷,偏向于合并連接。
有很多種方法可以用來找出哪些SQL語句需要優化,但是很久以來,最簡單的方法都是分析保存在V$SQL視圖中的緩存的SQL信息。通過V$SQL視圖,可以確定具有高消耗時間、CUP和IO讀取的SQL語句。
1.查看總消耗時間最多的前10條SQL語句
select *
from (select v.sql_id,
v.child_number,
v.sql_text,
v.elapsed_time,
v.cpu_time,
v.disk_reads,
rank() over(order by v.elapsed_time desc) elapsed_rank
from v$sql v) a
where elapsed_rank = 10;
2.查看CPU消耗時間最多的前10條SQL語句
select *
from (select v.sql_id,
v.child_number,
v.sql_text,
v.elapsed_time,
v.cpu_time,
v.disk_reads,
rank() over(order by v.cpu_time desc) elapsed_rank
from v$sql v) a
where elapsed_rank = 10;
3.查看消耗磁盤讀取最多的前10條SQL語句
select *
from (select v.sql_id,
v.child_number,
v.sql_text,
v.elapsed_time,
v.cpu_time,
v.disk_reads,
rank() over(order by v.disk_reads desc) elapsed_rank
from v$sql v) a
where elapsed_rank = 10;
希望能幫到您!
在日常基于數據庫應用的開發過程中,我們經常需要對多個表或者數據源進行關聯查詢而得出我們需要的結果集。那么Oracle到底存在著哪幾種連接方式?優化器內部又是怎樣處理這些連接的?哪種連接方式又是適合哪種查詢需求的?只有對這些問題有了清晰的理解后,我們才能針對特定的查詢需求選擇合適的連接方式,開發出健壯的數據庫應用程序。選擇合適的表連接方法對SQL語句運行的性能有著至關重要的影響。下面我們就Oracle常用的一些連接方法及適用情景做一個簡單的介紹。
3.1 嵌套循環連接(nested loop)
嵌套循環連接的工作方式是這樣的:
1、 Oracle首先選擇一張表作為連接的驅動表,這張表也稱為外部表(Outer Table)。由驅動表進行驅動連接的表或數據源稱為內部表(Inner Table)。
2、 提取驅動表中符合條件的記錄,與被驅動表的連接列進行關聯查詢符合條件的記錄。在這個過程中,Oracle首先提取驅動表中符合條件的第一條記錄,再與內部表的連接列進行關聯查詢相應的記錄行。在關聯查詢的過程中,Oracle會持續提取驅動表中其他符合條件的記錄與內部表關聯查詢。這兩個過程是并行進行的,因此嵌套循環連接返回前幾條記錄的速度是非常快的。在這里需要說明的是,由于Oracle最小的IO單位為單個數據塊,因此在這個過程中Oracle會首先提取驅動表中符合條件的單個數據塊中的所有行,再與內部表進行關聯連接查詢的,然后提取下一個數據塊中的記錄持續地循環連接下去。當然,如果單行記錄跨越多個數據塊的話,就是一次單條記錄進行關聯查詢的。
3、 嵌套循環連接的過程如下所示:
Nested loop
Outer loop
Inner loop
我們可以看出這里面存在著兩個循環,一個是外部循環,提取驅動表中符合條件的每條記錄。另外一個是內部循環,根據外循環中提取的每條記錄對內部表進行連接查詢相應的記錄。由于這兩個循環是嵌套進行的,故此種連接方法稱為嵌套循環連接。
嵌套循環連接適用于查詢的選擇性強、約束性高并且僅返回小部分記錄的結果集。通常要求驅動表的記錄(符合條件的記錄,通常通過高效的索引訪問)較少,且被驅動表連接列有唯一索引或者選擇性強的非唯一索引時,嵌套循環連接的效率是比較高的。
嵌套循環連接驅動表的選擇也是連接中需要著重注意的一點,有一個常見的誤區是驅動表要選擇小表,其實這是不對的。假如有兩張表A、B關聯查詢,A表有1000000條記錄,B表有10000條記錄,但是A表過濾出來的記錄只有10條,這時候顯然用A表當做驅動表是比較合適的。因此驅動表是由過濾條件限制返回記錄最少的那張表,而不是根據表的大小來選擇的。
在外連接查詢中,如果走嵌套循環連接的話,那么驅動表必然是沒有符合條件關聯的那張表,也就是后面不加(+)的那張表。這是由于外連接需要提取可能另一張表沒符合條件的記錄,因此驅動表需要是那張我們要返回所有符合條件記錄的表。比如下面這個查詢,
嵌套循環連接返回前幾行的記錄是非常快的,這是因為使用了嵌套循環后,不需要等到全部循環結束再返回結果集,而是不斷地將查詢出來的結果集返回。在這種情況下,終端用戶將會快速地得到返回的首批記錄,且同時等待Oracle內部處理其他記錄并返回。如果查詢的驅動表的記錄數非常多,或者被驅動表的連接列上無索引或索引不是高度可選的情況,嵌套循環連接的效率是非常低的
-- 刪除原表
drop table t1;
-- 建立測試表
create table t1(
f1 varchar2(10),
f2 varchar2(1000)
)
tablespace CTL
pctfree 98;
-- 填充測試內容
insert into t1(f1,f2)
select rownum, lpad(rownum,700,'0')
from dba_tables a, dba_tab_cols b
where a.owner = b.owner
and rownum 10000;
commit;
-- 檢查測試內容格式
select sys.dbms_rowid.rowid_block_number(rowid), f1, f2 from t1;
-- 每條記錄都存儲在單獨的數據塊中
select count( distinct sys.dbms_rowid.rowid_block_number(rowid)) from t1;
/*
用同樣的方式建立表t2
*/
-- 刪除原表
drop table t2;
-- 建立測試表
create table t2(
f1 varchar2(10),
f2 varchar2(1000)
)
tablespace CTL
pctfree 98;
-- 填充測試內容
insert into t2(f1,f2)
select rownum * 10, lpad(rownum * 10,700,'0')
from dba_tables a, dba_tab_cols b
where a.owner = b.owner
and rownum 1000;
commit;
-- 檢查測試內容格式
select sys.dbms_rowid.rowid_block_number(rowid), f1, f2 from t2;
-- 每條記錄都存儲在單獨的數據塊中
select count( distinct sys.dbms_rowid.rowid_block_number(rowid)) from t2;
create index ind_t1_f1 on t1(f1);
create index ind_t2_f1 on t2(f1);
--首先我們來看使用nested loop關聯方式, 不同表作為驅動時的情況.
1, 表t2作為驅動表
select /*+ ordered use_nl(t1 , t2)*/
t1.f1, t2.f1
from ctl.t2 t2,ctl.t1 t1
where t1.f1 = t2.f1
and t1.f1 1000;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=84 Card=4 Bytes=56)
1 0 NESTED LOOPS (Cost=84 Card=4 Bytes=56)
2 1 TABLE ACCESS (FULL) OF 'T2' (Cost=2 Card=82 Bytes=574)
3 1 INDEX (RANGE SCAN) OF 'IND_T1_F1' (NON-UNIQUE) (Cost=1 C
ard=1 Bytes=7)
Cost = outer access cost + (inner access cost * outer cardinality)
Cost = 2 + 1 * 82 = 84;
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2020 consistent gets
23 physical reads
0 redo size
2650 bytes sent via SQL*Net to client
721 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
99 rows processed
2, t1作為驅動表
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=4 Bytes=56)
1 0 NESTED LOOPS (Cost=6 Card=4 Bytes=56)
2 1 TABLE ACCESS (FULL) OF 'T1' (Cost=2 Card=4 Bytes=28)
3 1 INDEX (RANGE SCAN) OF 'IND_T2_F1' (NON-UNIQUE) (Cost=1 C
ard=1 Bytes=7)
Cost = outer access cost + (inner access cost * outer cardinality)
Cost = 2 + 1 * 4 = 84;
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
11123 consistent gets
3 physical reads
0 redo size
2650 bytes sent via SQL*Net to client
721 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
99 rows processed
3.2, 哈希連接(hash join)
哈希連接分為兩個階段,如下。
1、 構建階段:優化器首先選擇一張小表做為驅動表,運用哈希函數對連接列進行計算產生一張哈希表。通常這個步驟是在內存(hash_area_size)里面進行的,因此運算很快。
2、 探測階段:優化器對被驅動表的連接列運用同樣的哈希函數計算得到的結果與前面形成的哈希表進行探測返回符合條件的記錄。這個階段中如果被驅動表的連接列的值沒有與驅動表連接列的值相等的話,那么這些記錄將會被丟棄而不進行探測
哈希連接比較適用于返回大數據量結果集的連接。
使用哈希連接必須是在CBO模式下,參數hash_join_enabled設置為true,
哈希連接只適用于等值連接。從Oracle9i開始,哈希連接由于其良好的性能漸漸取代了原來的排序合并連接。
SQL select /*+ ordered use_hash(t1 , t2) */
t1.f1, t2.f1
from ctl.t1 t1,ctl.t2 t2
where t1.f1 = t2.f1 2 3 4 ;
999 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=82 Bytes=1148
)
1 0 HASH JOIN (Cost=5 Card=82 Bytes=1148)
2 1 TABLE ACCESS (FULL) OF 'T1' (Cost=2 Card=82 Bytes=574)
3 1 TABLE ACCESS (FULL) OF 'T2' (Cost=2 Card=82 Bytes=574)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
11113 consistent gets
0 physical reads
0 redo size
23590 bytes sent via SQL*Net to client
1381 bytes received via SQL*Net from client
68 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
999 rows processed
3.3, 排序合并連接(merge join)
排序合并連接的方法非常簡單。在排序合并連接中是沒有驅動表的概念的,兩個互相連接的表按連接列的值先排序,排序完后形成的結果集再互相進行合并連接提取符合條件的記錄。相比嵌套循環連接,排序合并連接比較適用于返回大數據量的結果。
排序合并連接在數據表預先排序好的情況下效率是非常高的,也比較適用于非等值連接的情況,比如、=、=等情況下的連接(哈希連接只適用于等值連接)。由于Oracle中排序操作的開銷是非常消耗資源的,當結果集很大時排序合并連接的性能很差,于是Oracle在7.3之后推出了新的連接方式——哈希連接。
1, rbo模式;
2, 不等于關聯( = = )
3, hash_join_enabled = false;
4, 數據源已排序
通過配置本地數據庫的tns配置文件實現:
去oracle安裝目錄下oracle\product\10.2.0\db_2\NETWORK\ADMIN\ 找到tnsnames.ora,用記事本打開,里邊有遠程數據庫的tns連接配置串如下
ORCL23 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.3.23)(PORT = 1521))
)
(CONNECT_DATA =
(SID = ORCL)
)
)
添加好ip、端口和目標數據庫的實例名(SID),然后確保tns名稱(ORCL23)在整個文檔中唯一,保存后打開數據庫連接工具,輸入遠程數據庫上的用戶名密碼,選擇數據庫對象為你配置的連接名就可以了
ORACLE 不會自動建立索引,之所以快是因為從內存中讀取比disk IO要快的原因。
LZ的概念理解有誤,我來舉例說明下。
ORACLE data一般緩存在SGA中的data cache中 1.表A有10000條數據,在0:00時刻對其進行查詢,則將表A的所有數據塊從disk緩存至data cache中。因此第二次查詢時直接從data cache中獲得速度變快。 2.0:05時刻 對表A進行更新等操作,20000行。再次對表A進行查詢,之前沒有變化的數據塊仍然直接從data cache中直接獲得。發生過變更,或新增的數據塊,需要重新從disk讀入data cache中,如果data cache空間已滿,就會將之前發生變更的臟數據塊及不常使用的數據塊清空出data cache,然后緩存新的數據塊。 因此整個過程中,不會出現你說的只能查到緩存數據的現象。分析你遇到的問題,很有可能是你用userA 進行查詢后發現表10000行,然后使用userB進行更新至20000行,但是userB并沒有commit。因此userA在查詢時仍然只能看到10000行。
本文標題:怎么看oracle的io,怎么看oracle的用戶名
本文URL:http://m.2m8n56k.cn/article8/hojdip.html
成都網站建設公司_創新互聯,為您提供動態網站、做網站、全網營銷推廣、用戶體驗、網站制作、靜態網站
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:[email protected]。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯