暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【SQL杂货铺】-table

原创 闫伟 2023-01-17
445


1、

1.1、查看表定义

select dbms_metadata.get_ddl('TABLE','TABLE_NAME','TABLE_OWNER') from dual;

 

1.2、取得一个表的所有字段名并用逗号分割

select max(substr(SYS_CONNECT_BY_PATH(COLUMN_NAME, ','),2)) col from (

select COLUMN_NAME,column_id from user_tab_columns where table_name='&tablename')

start with column_id=1 connect by column_id=rownum;

1.3、查询某张表被哪些存储过程或者视图用到

--V表示视图,P表示存储过程,tablename为需要查询被引用的表名称

select distinct object_name(id) from syscomments  where id in (select id from sysobjects where type in('V','P')) and text like '%&tablename%';

--或者

select a.* from sysobjects a, syscomments b where a.id = b.id and b.text like '%tablename%';

 

1.4、查找某表或某索引增长的历史信息

通过AWR来查找一段时间内,数据库段对象(堆表、索引)等的空间增长信息。

在Oracle 10g开始awr自动负载仓库引入了dba_hist_seg_stat视图,该视图记录了快照时间内segment-level段级的历史统计信息

column owner format a16

column object_name format a36

column start_day format a11

column block_increase format 9999999999

 

select obj.owner, obj.object_name,

         to_char(sn.BEGIN_INTERVAL_TIME,'RRRR-MON-DD') start_day,

         sum(a.db_block_changes_delta) block_increase

from dba_hist_seg_stat a,

         dba_hist_snapshot sn,

         dba_objects obj

where sn.snap_id = a.snap_id

and obj.object_id = a.obj#

and obj.owner not in ('SYS','SYSTEM')

and end_interval_time between to_timestamp('01-MAR-2020','DD-MON-RRRR')

         and to_timestamp('30-MAR-2020','DD-MON-RRRR')

and object_name like '%&object_name%'

group by obj.owner, obj.object_name,

         to_char(sn.BEGIN_INTERVAL_TIME,'RRRR-MON-DD')

order by obj.owner, obj.object_name

/

1.5、物理IO前10的表

SELECT TABLE_NAME,TOTAL_PHYS_IO

FROM ( SELECT OWNER||'.'||OBJECT_NAME AS TABLE_NAME,

             SUM(VALUE) AS TOTAL_PHYS_IO

      FROM  V$SEGMENT_STATISTICS

      WHERE OWNER!='SYS' AND OBJECT_TYPE='TABLE'

 AND STATISTIC_NAME IN ('physical reads','physical reads direct',

                      'physical writes','physical writes direct')

      GROUP BY OWNER||'.'||OBJECT_NAME

      ORDER BY TOTAL_PHYS_IO DESC)

WHERE ROWNUM <=10;

1.6、碎片程度高的表

Set linesize 1000 pagesize 1000

SELECT TABLE_NAME,(BLOCKS*8192/1024/1024)"理论大小M",

(NUM_ROWS*AVG_ROW_LEN/1024/1024/0.9)"实际大小M",

round((NUM_ROWS*AVG_ROW_LEN/1024/1024/0.9)/(BLOCKS*8192/1024/1024),3)*100||'%' "实际使用率%"

FROM USER_TABLES where blocks>100 and (NUM_ROWS*AVG_ROW_LEN/1024/1024/0.9)/(BLOCKS*8192/1024/1024)<0.3

order by (NUM_ROWS*AVG_ROW_LEN/1024/1024/0.9)/(BLOCKS*8192/1024/1024) desc;

1.7、集群因子clustering_factor高的表

集群因子越接近块数越好,接近行数则说明索引列的列值相等的行分布极度散列,可能不走索引扫描而走全表扫描

select tab.table_name,tab.blocks,tab.num_rows,ind.index_name,ind.clustering_factor,

round(nvl(ind.clustering_factor,1)/decode(tab.num_rows,0,1,tab.num_rows),3)*100||'%' "集群因子接近行数"

from dba_tables tab, dba_indexes ind where tab.table_name=ind.table_name

and tab.blocks>100 and nvl(ind.clustering_factor,1)/decode(tab.num_rows,0,1,tab.num_rows) between 0.35 and 3;

1.8、获取XX用户下所有表的表名与其数据量

--1、创建存储过程和基础表table_rows

create or replace procedure testhwb(own in VARCHAR2)

is

  v_table varchar(100);

  v_num   number;

  v_sql   varchar(500);

  cursor c1 is

    select table_name from dba_tables where owner = "own";

  --如果没有dba权限则修改成:select table_name from user_tables;

begin

  DBMS_OUTPUT.ENABLE(buffer_size => null); --表示输出buffer不受限制

  open c1;

  loop

    fetch c1

      into v_table;

    if c1%found then

      v_sql := 'select count(*) from ||own||"."||v_table';

      execute immediate v_sql

        into v_num;

      dbms_output.put_line('table_name:' || v_table || ' count_rows: ' ||

                           v_num);

      insert into table_rows values (v_table, v_num);

    else

      exit;

    end if;

  end loop;

  commit;

  close c1;

end;

 

 

--2、执行存储过程

begin

  testhwb('NWPP_TEST');

end;

 

1.9、查看高水位线

HWM = total_blocks- Unused Blocks +1

--1、创建存储过程

create or replace procedure show_space(p_segname   in varchar2,

                                       p_owner     in varchar2 default user,

                                       p_type      in varchar2 default 'TABLE',

                                       p_partition in varchar2 default NULL) as

  l_total_blocks       number;

  l_total_bytes        number;

  l_unused_blocks      number;

  l_unused_bytes       number;

  l_LastUsedExtFileId  number;

  l_LastUsedExtBlockId number;

  l_last_used_block    number;

  procedure p(p_label in varchar2, p_num in number) is

  begin

    dbms_output.put_line(rpad(p_label, 40, '.') || p_num);

  end;

begin

  dbms_space.unused_space(segment_owner             => p_owner,

                          segment_name              => p_segname,

                          segment_type              => p_type,

                          partition_name            => p_partition,

                          total_blocks              => l_total_blocks,

                          total_bytes               => l_total_bytes,

                          unused_blocks             => l_unused_blocks,

                          unused_bytes              => l_unused_bytes,

                          last_used_extent_file_id  => l_LastUsedExtFileId,

                          last_used_extent_block_id => l_LastUsedExtBlockId,

                          last_used_block           => l_last_used_block);

  p('Total Blocks', l_total_blocks);

  p('Total Bytes', l_total_bytes);

  p('Unused Blocks', l_unused_blocks);

  p('Unused Bytes', l_unused_bytes);

  p('Last Used Ext FileId', l_LastUsedExtFileId);

  p('Last Used Ext BlockId', l_LastUsedExtBlockId);

  p('Last Used Block', l_last_used_block);

end;

/

 

--2、查看ssys.aud$的HWM线

set serveroutput on

exec show_space(p_segname=>'AUD$',p_owner =>'SYS',p_type => 'TABLE');  

 

1.10、一键检查数据库高水位表并回收

--1、高水位表排序

SELECT 'alter table '||table_name||' move' ,table_name,

       tablespace_name,

       status,

       last_analyzed,

       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'

 ORDER BY 9 DESC;

--2、回收高水位表

//第一种方法:MOVE回收高水位(move需要额外的空间空间,move后需要重建索引)

alter table my_objects move;

//第二种方法:shrink回收高水位(shrink后不需要重建索引,如果一个表的索引比较多,shrink过程中用来维护index的成本也会比较高,,shrink不影响dml操作,能在线)

alter table my_objects enable row movement;

alter table my_objects shrink space;

--重新收集统计信息(针对表手动收集)

ANALYZE TABLE  TABLE_NAME  COMPUTE STATISTICS;

1.11、recover_truncate_tab_plsql

用于恢复truncate table,恢复的主要思路:

1)通过logmnr找到被truncate表上一次的data_object_id。有一种特殊情况:如果表只被truncate一次,那么上次的data_object_id和object_id是一致的。

2)通过dba_free_space获取所有free block。

3)通过dbms_rowid.rowid_create来创建rowid。

4)利用rowid来抽取数据。

-- 用于恢复truncate table

-- 作者:Oracle恢复实录公众号作者

-- 2020-01-13

-- 详细请参考文章《TRUNCATE TABLE恢复系列二:PL/SQL恢复》https://www.modb.pro/db/14957

declare

   v_fno number;

   v_s_bno number;

   v_e_bno number;

   v_rowid rowid;

   nrows number;

begin

   for i in (select relative_fno,block_id,blocks

               from dba_extents

                          where owner='RESCUREORA' and segment_name='RESCUREORA_TABLE' and extent_id=0  -- RESCUREORA和RESCUREORA_TABLE 均为原表

             union all

             select relative_fno,block_id,blocks

               from dba_free_space

              where tablespace_name in

                          (select tablespace_name

                             from dba_tables

                                where owner='RESCUREORA' and table_name='RESCUREORA_TABLE')  -- RESCUREORA和RESCUREORA_TABLE 均为原表

                         union all

                         select relative_fno,block_id,blocks from (

                         select relative_fno,block_id,blocks,row_number()over(partition by owner,segment_name,PARTITION_NAME order by extent_id desc) rn

               from dba_extents

              where tablespace_name in

                          (select tablespace_name

                             from dba_tables

                                where owner='RESCUREORA' and table_name='RESCUREORA_TABLE') and extent_id>0)  -- RESCUREORA和RESCUREORA_TABLE 均为原表

                           where rn=1) loop

   v_fno:=i.relative_fno;

   v_s_bno:=i.block_id;

   v_e_bno:=i.block_id+i.blocks-1;

       for j in v_s_bno .. v_e_bno loop

        begin

         for x in 0 .. 999 loop

           v_rowid:=dbms_rowid.rowid_create(1, 87903,v_fno,j,x); -- 87903 为dataobj#

           insert into sys.rescureora_table select * from rescureora.rescureora_table where rowid=v_rowid;

            -- 其中:sys.rescureora_table 为目标表,rescureora.rescureora_table为原表

         end loop;

        exception

          when others then

            null;

        end;

        commit;

       end loop;

    end loop;

end;

/

 

 

1.12、查询热点块和热点块的操作

---查询热块对象

SELECT *  

  FROM (SELECT O.OWNER, O.OBJECT_NAME, O.OBJECT_TYPE, SUM(TCH) TOUCHTIME

          FROM X$BH B, DBA_OBJECTS O  

         WHERE B.OBJ = O.DATA_OBJECT_ID  

           AND B.TS# > 0  

         GROUP BY O.OWNER, O.OBJECT_NAME, O.OBJECT_TYPE  

         ORDER BY SUM(TCH) DESC)  

 WHERE ROWNUM <= 10;   

--查找热点块操作语句  

SELECT /*+rule*/

 HASH_VALUE, SQL_ID,SQL_TEXT

  FROM V$SQLTEXT

 WHERE (HASH_VALUE, ADDRESS) IN

       (SELECT A.HASH_VALUE, A.ADDRESS

          FROM V$SQLTEXT A,

               (SELECT DISTINCT A.OWNER, A.SEGMENT_NAME, A.SEGMENT_TYPE

                  FROM DBA_EXTENTS A,

                       (SELECT DBARFIL, DBABLK

                          FROM (SELECT DBARFIL, DBABLK

                                  FROM X$BH

                                 ORDER BY TCH DESC)

                         WHERE ROWNUM < 11) B

                 WHERE A.RELATIVE_FNO = B.DBARFIL

                   AND A.BLOCK_ID <= B.DBABLK

                   AND A.BLOCK_ID + A.BLOCKS > B.DBABLK) B

         WHERE A.SQL_TEXT LIKE '%' || B.SEGMENT_NAME || '%'

           AND B.SEGMENT_TYPE = 'TABLE')

 ORDER BY HASH_VALUE, ADDRESS, PIECE;

1.13、查找lobsegment、lobindex对应的表

当表含有LOB字段时,Oracle会为含有LOB字段的列单独创建一个lobsegment,同时还会创建一个lobindex。那么lobsegment、lobindex是如何与表关联起来的呢?

select owner, table_name, column_name, segment_name, index_name  from dba_lobs where segment_name='I_TRANSACTION_XML_BLOB'

 

 

1.14、大表删除如何监控delele进度

大表删除时需要注意观察UNDO表空间使用率(观察连接的是哪个实例,然后看对应的UNDO空间,假设UDNOTBS1使用了比较多空间,就需要连接到RFDB2实例,充分利用UNDO空间),归档空间情况(虽然已经nologging,但归档日志还是有发生切换,需要注意空间使用情况),数据库服务器负载和告警日志。

--1、v$transaction查看删除进度

select start_time,start_scnb,used_ublk,used_urec,log_io,phy_io from v$transaction;

说明:

start_time --> start_time

start_scnb --> 开始的scn

used_ublk --> 占用的undo block

used_urec --> undo记录的行数

log_io    --> 逻辑io 注意并非Consistent gets,有专门一列:CR_GET

phy_io    --> 物理io

--2、查询正运行事务

用如下SQL查询到正在运行的事务,如其used_urec字段不断增加,说明该事务正在继续,如果该字段不断下降,说明该事物正在回滚。

SELECT a.sid, a.username, b.xidusn, b.used_urec, b.used_ublk from v$session a, v$transaction b WHERE a.saddr = b.ses_addr;

--3、监控数据库中的回滚事务

对于数据库中的回滚事务,可以查看下面的视图监控:

V$FAST_START_SERVERS

V$FAST_START_TRANSACTIONS

分别查看回滚的进程信息和事务信息

1.15、在线调整oracle回滚的速度及查看回滚速度

关于fast_start_parallel_rollback参数,此参数决定了回滚启动的并行次数,在繁忙的系统或者IO性能较差的系统,如果出现大量回滚操作,会显著影响系统系统,可以通过调整此参数来降低影响。

FAST_START_PARALLEL_ROLLBACK specifies the degree of parallelism used when recovering terminated transactions. Terminated transactions are transactions that are active before a system failure. If a system fails when there are uncommitted parallel DML or DDL transactions, then you can speed up transaction recovery during startup by using this parameter.

Values:

    FALSE:

    Parallel rollback is disabled

    LOW:

    Limits the maximum degree of parallelism to 2 * CPU_COUNT

    HIGH:

    Limits the maximum degree of parallelism to 4 * CPU_COUNT

If you change the value of this parameter, then transaction recovery will be stopped and restarted with the new implied degree of parallelism.

--1、查看回滚进度

USN:事务对应的undo段

STATE:事务的状态,可选的值为(BE RECOVERED, RECOVERED, or RECOVERING)       

UNDOBLOCKSDONE:已经完成的undo块

UNDOBLOCKSTOTAL:总的undo数据块

CPUTIME:已经回滚的时间,单位是秒

RCVSERVERS:回滚的并行进程数

 

select usn,

       state,

       undoblocksdone,

       undoblockstotal,

       CPUTIME,

       pid,

       xid,

       rcvservers

  from v$fast_start_transactions;

--或者以下sql

select ktuxeusn USN, ktuxeslt Slot, ktuxesqn Seq, ktuxesta State, ktuxesiz Undo from sys.ktuxe

  where ktuxesta <> 'INACTIVE'

  and ktuxecfl like '%DEAD%'

  order by ktuxesiz asc;

 

--2、计算回滚时间

select  undoblockstotal "Total", undoblocksdone "Done", undoblockstotal-undoblocksdone

"ToDo",decode(cputime,0,'unknown',to_char(sysdate+(((undoblockstotal-undoblocksdone)

/ (undoblocksdone / cputime)) / 86400),'yyyy-mm-dd hh24:mi:ss'))

"Estimated time to complete",to_char(sysdate,'yyyy-mm-dd hh24:mi:ss')

from v$fast_start_transactions;

 

--3、设置fast_start_parallel_rollback加快undo回滚的速度,在线修改,立即生效

alter system set fast_start_parallel_rollback=HIGH scope=both;

 

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论