- 查詢碎片
SELECT table_name,
ROUND ( (blocks * 8), 2) "高水位空間 k",
ROUND ( (num_rows * avg_row_len / 1024), 2) "真實使用空間 k",
ROUND ( (blocks * 10 / 100) * 8, 2) "預留空間(pctfree) k",
ROUND (
( blocks * 8
- (num_rows * avg_row_len / 1024)
- blocks * 8 * 10 / 100),
2)
"浪費空間 k"
FROM user_tables
WHERE temporary = 'N'
and table_name in ('MAIN_TABLE1',
'MAIN_TABLE2',
'MAIN_TABLE3'
...)
ORDER BY 5 DESC;
說明:如果有碎片浪費空間最好都清理一下。建議清理碎片程度計算範圍
1-(真實使用空間/高水位空間)>8%
2、主表開啓行遷移
begin
for idx in (SELECT 'alter table ' || table_name || ' enable row movement;' row_cur
FROM user_tables
WHERE
table_name in ('MAIN_TABLE1',
'MAIN_TABLE2',
'MAIN_TABLE3'
...)
ORDER BY 5 DESC;
) loop
begin
execute immediate (idx.row_cur);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(idx.row_cur);
END;
end loop;
end;
說明:這是批量執行開啓錶行遷移。在執行行遷移時,將無法進行DML操作。
3、收縮表空間
begin
for idx in (SELECT 'alter table ' || table_name || ' shrink space ;' row_cur
FROM user_tables
WHERE
table_name in ('MAIN_TABLE1',
'MAIN_TABLE2',
'MAIN_TABLE3'
...)
ORDER BY 5 DESC;
) loop
begin
execute immediate (idx.row_cur);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(idx.row_cur);
END;
end loop;
end;
說明:這是批量進行表空間收縮。對於大表收縮時間話費可能比較長,中間切勿中斷。
4、收縮索引空間
begin
for idx in (SELECT 'alter index' || index_name || ' shrink space ;' row_cur
FROM user_indexes
WHERE
table_name in ('MAIN_TABLE1',
'MAIN_TABLE2',
'MAIN_TABLE3'
...)
ORDER BY 5 DESC;
) loop
begin
execute immediate (idx.row_cur);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(idx.row_cur);
END;
end loop;
end;
說明:這是批量進行索引空間收縮對於大表索引收縮時間話費可能比較長,中間切勿中斷。
5、主表關閉行遷移
begin
for idx in (SELECT 'alter table ' || table_name || ' disable row movemnt;' row_cur
FROM user_tables
WHERE
table_name in ('MAIN_TABLE1',
'MAIN_TABLE2',
'MAIN_TABLE3'
...)
ORDER BY 5 DESC;
) loop
begin
execute immediate (idx.row_cur);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(idx.row_cur);
END;
end loop;
end;
說明:關閉行遷移以後,纔可以進行DML操作。切記打開以後,記得關閉行遷移。
6、重建表索引
begin
for idx in (SELECT 'alter index' || index_name || ' rebuild online;' row_cur
FROM user_indexes
WHERE
table_name in ('MAIN_TABLE1',
'MAIN_TABLE2',
'MAIN_TABLE3'
...)
ORDER BY 5 DESC;
) loop
begin
execute immediate (idx.row_cur);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(idx.row_cur);
END;
end loop;
end;
說明:經過表和索引收縮以後,進行重建索引。使索引正常排列。
7、收集主表信息
begin dbms_stats.gather_table_stats(user,'MAIN_TABLE1',cascade=>true);end;
begin dbms_stats.gather_table_stats(user,'MAIN_TABLE2',cascade=>true);end;
begin dbms_stats.gather_table_stats(user,'MAIN_TABLE3',cascade=>true);end;
說明:這是收集主表統計信息,當索引數據準確後,需統計信息收集,使得表統計信息準確,Oracle優化器基於成本開銷才能選擇最優的執行路徑,才能使得SQL語句執行最優執行計劃,SQL性能得以提高。
8、SQL語句性能分析
1)、數據準備
Drop table test2;
create table test2 (id number,crt_time date);
begin
for i in 1 .. 1000000 loop
insert into test2 (id, crt_time) values (i, sysdate);
end loop;
end;
2)、性能測試--執行計劃
--沒加索引;
--查詢
select * from test2 where id between 123 and 77789 ;
--執行計劃
如何查看一條SQL的執行計劃?
選中查詢語句,然後按F5(菜單:工具——>解釋計劃)
--增加索引
Create unique index idx_test2_id on test2(id);
--查詢
select * from test2 where id between 123 and 77789 ;
--執行計劃
如何查看一條SQL的執行計劃?
選中查詢語句,然後按F5(菜單:工具——>解釋計劃)
根據耗費對比,加了索引後的SQL性能比沒加索引快3倍以上。
9、分析表和索引的語句
analyze table TABLE_NAME compute statistics
select ' analyze index '||index_name ||' compute statistics ;' from user_indexes ui where ui.table_name='TABLE_NAME ' ;
- 判斷索引有效和無效
select ui.index_name,status from user_indexes ui where table_name='LIS_RESULT'
說明:如果STATUS爲VALID那麼索引爲有效。UNUSABLE爲無效。
如果手工將索引 IDX_LIS_RESULT1 設爲無效 可以如下操作:
alter index IDX_LIS_RESULT1 unusable;
備註說明:文章中table_name是目標庫查詢的主表。其他小數據量的表可以不查詢碎片。