- 查询碎片
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是目标库查询的主表。其他小数据量的表可以不查询碎片。
来源:CSDN
作者:DBA_fashion
链接:https://blog.csdn.net/p6620582/article/details/103964862