Oracle学习笔记(六)

Oralce行定位与rowid:

drop table t purge;
create table t as select * from dba_objects;
create index idx_object_id on t(object_id);
set linesize 1000
set autotrace traceonly 

--方法1(全表扫描)
select /*+full(t)*/ * from t where object_id=2;

--方法2(索引扫描)
select * from t where object_id=2;


--方法3(rowid扫描)
set autotrace off 
select rowid from t where object_id=2;

set autotrace traceonly 
select * from t where object_id=2 and rowid='AAAYiZAALAAAADLAAw';


SQL> select /*+full(t)*/ * from t where object_id=2;
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |   207 |   291   (1)| 00:00:04 |
|*  1 |  TABLE ACCESS FULL| T    |     1 |   207 |   291   (1)| 00:00:04 |
--------------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       1044  consistent gets

          

SQL> select * from t where object_id=2;
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |               |     1 |   207 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T             |     1 |   207 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_OBJECT_ID |     1 |       |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
       


SQL> select * from t where object_id=2 and rowid='AAAYiZAALAAAADLAAw';
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |      |     1 |   219 |     1   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY USER ROWID| T    |     1 |   219 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          1  consistent gets

  

---启动大小为2K的块新建表空间(WINDOWS下只能使用2K,4K,8K和16K  
alter system set db_2k_cache_size=100M;
drop tablespace tbs_ljb_2k including contents and datafiles;
create tablespace TBS_LJB_2k 
blocksize 2K
datafile  'D:\ORACLE\ORADATA\TEST11G\TBS_LJB_2K_01.DBF' size 100M  
autoextend on  
extent management local 
segment space management auto;
create table t_2k tablespace tbs_ljb_2k as select * from dba_objects;

---启动大小为4K的块新建表空间
alter system set db_4k_cache_size=100M;
drop tablespace tbs_ljb_4k including contents and datafiles;
create tablespace TBS_LJB_4k 
blocksize 4K
datafile  'D:\ORACLE\ORADATA\TEST11G\TBS_LJB_4K_01.DBF' size 100M  
autoextend on  
extent management local 
segment space management auto;
create table t_4k tablespace tbs_ljb_4k as select * from dba_objects;


---启动大小为8K的块新建表空间(默认就是8K)

drop table t_8k purge;
create table t_8k as select * from dba_objects;

---启动大小为16K的块新建表空间
alter system set db_16k_cache_size=100M;
drop tablespace tbs_ljb_16k including contents and datafiles;
create tablespace TBS_LJB_16k 
blocksize 16K
datafile  'D:\ORACLE\ORADATA\TEST11G\TBS_LJB_16K_01.DBF' size 100M  
autoextend on  
extent management local 
segment space management auto;
create table t_16k tablespace tbs_ljb_16k as select * from dba_objects;


-----------------------------------------------------------------------------------------
--开始试验,发现代价和逻辑读都是以此变少!

SET autotrace traceonly

select count(*) from t_2k;
/

select count(*) from t_4k;
/

select count(*) from t_8k;
/

select count(*) from t_16k;
/

--但是也不是块越大越好,要注意热点块竞争。

SQL> select count(*) from t_2k;
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |   891   (1)| 00:00:11 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| T_2K | 83292 |   891   (1)| 00:00:11 |
-------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       4511  consistent gets
        

SQL> select count(*) from t_4k;
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |   480   (1)| 00:00:06 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| T_4K | 63139 |   480   (1)| 00:00:06 |
-------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       2137  consistent gets        

SQL> select count(*) from t_8k;
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |   291   (1)| 00:00:04 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| T_8K | 62320 |   291   (1)| 00:00:04 |
-------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       1043  consistent gets
             
SQL> select count(*) from t_16k;
--------------------------------------------------------------------
|   0 | SELECT STATEMENT   |       |     1 |   200   (1)| 00:00:03 |
|   1 |  SORT AGGREGATE    |       |     1 |            |          |
|   2 |   TABLE ACCESS FULL| T_16K | 80144 |   200   (1)| 00:00:03 |
--------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        517  consistent gets

  

--查看系统Oracle块的大小
sqlplus "/ as sysdba"
show parameter db_block_size
select block_size
 from dba_tablespaces 
where tablespace_name='SYSTEM';


---启动大小为2K的块新建表空间(WINDOWS下只能使用2K,4K,8K和16K)
alter system set db_2k_cache_size=100M;
drop tablespace tbs_ljb_2k including contents and datafiles;
create tablespace TBS_LJB_2k 
blocksize 2K
datafile  'D:\ORACLE\ORADATA\TEST11G\TBS_LJB_2K_01.DBF' size 100M  
autoextend on  
extent management local 
segment space management auto;
create table t_2k tablespace tbs_ljb_2k as select * from dba_objects where rownum<=100;


---启动大小为4K的块新建表空间
alter system set db_4k_cache_size=100M;
drop tablespace tbs_ljb_4k including contents and datafiles;
create tablespace TBS_LJB_4k 
blocksize 4K
datafile  'D:\ORACLE\ORADATA\TEST11G\TBS_LJB_4K_01.DBF' size 100M  
autoextend on  
extent management local 
segment space management auto;
create table t_4k tablespace tbs_ljb_4k as select * from dba_objects where rownum<=100;


---启动大小为8K的块新建表空间(默认就是8K)
drop table t_8k purge;
create table t_8k as select * from dba_objects where rownum<=100;


---启动大小为16K的块新建表空间
alter system set db_16k_cache_size=100M;
drop tablespace tbs_ljb_16k including contents and datafiles;
create tablespace TBS_LJB_16k 
blocksize 16K
datafile  'D:\ORACLE\ORADATA\TEST11G\TBS_LJB_16K_01.DBF' size 100M  
autoextend on  
extent management local 
segment space management auto;
create table t_16k tablespace tbs_ljb_16k as select * from dba_objects where rownum<=100;


--之前试验过块越大,逻辑读越少,但是实际情况并非块越大越好,还要注意热点块竞争。
-------------------------------------------------------------------------------------------------------------------------------------------
sqlplus "/ as sysdba"
grant all on DBMS_LOCK to ljb;

connect ljb/ljb

--创建一个包来构造各种JOB,分析问题
create or replace package pkg_test_block_size
 as
 procedure p_t_2k;
 procedure p_t_4k;
 procedure p_t_8k;
 procedure p_t_16k;
 procedure p_exec_2k_job;
 procedure p_exec_4k_job;
 procedure p_exec_8k_job;
 procedure p_exec_16k_job;
 procedure p_remove_job;
end pkg_test_block_size;
/ 

create or replace package body pkg_test_block_size
as
   procedure p_t_2k as
      begin
       for j in 1..1000 loop
        for i in (select * from t_2k ) loop
          null;
         end loop;
        end loop;
      end p_t_2k;

    procedure p_t_4k as
       begin
        for j in 1..1000 loop
         for i in (select * from t_4k ) loop
           null;
          end loop;
         end loop;
       end p_t_4k;

    procedure p_t_8k as
       begin
        for j in 1..1000 loop
         for i in (select * from t_8k ) loop
           null;
          end loop;
         end loop;
       end p_t_8k;

    procedure p_t_16k as
       begin
        for j in 1..1000 loop
         for i in (select * from t_16k ) loop
           null;
          end loop;
         end loop;
       end p_t_16k;


--创建JOB
   procedure p_exec_2k_job as
    JOBNO   NUMBER;
    BEGIN
      for i in 1..100 loop
       DBMS_JOB.SUBMIT( JOBNO,
                       'pkg_test_block_size.p_t_2k;',
                        SYSDATE,
                       'SYSDATE+1/1440');
      end loop;
      DBMS_LOCK.sleep(120);
     END p_exec_2k_job;

  procedure p_exec_4k_job as
   JOBNO   NUMBER;
    BEGIN
      for i in 1..100 loop
       DBMS_JOB.SUBMIT( JOBNO,
                       'pkg_test_block_size.p_t_4k;',
                        SYSDATE,
                       'SYSDATE+1/1440');
      end loop;
      DBMS_LOCK.sleep(120);
     END p_exec_4k_job;

 procedure p_exec_8k_job as
   JOBNO   NUMBER;
    BEGIN
      for i in 1..100 loop
       DBMS_JOB.SUBMIT( JOBNO,
                       'pkg_test_block_size.p_t_8k;',
                        SYSDATE,
                       'SYSDATE+1/1440');
       end loop;
       DBMS_LOCK.sleep(120);
     END p_exec_8k_job;

 procedure p_exec_16k_job as
   JOBNO   NUMBER;
    BEGIN
       for i in 1..100 loop
        DBMS_JOB.SUBMIT( JOBNO,
                        'pkg_test_block_size.p_t_16k;',
                         SYSDATE,
                        'SYSDATE+1/1440');
       end loop;
       DBMS_LOCK.sleep(120);
     END p_exec_16k_job;


 procedure p_remove_job as
     BEGIN
        for i in (select job from user_jobs )loop
         DBMS_JOB.remove(i.job);
        end loop;
      END p_remove_job;

END pkg_test_block_size;

drop table test_latch purge;
create table test_latch (block_size varchar2(10),id number,gets number , misses number, sleeps number, immediate_gets number);

--测试1.
delete from test_latch  where block_size='2k';
insert into test_latch select '2k',1,gets,misses,sleeps,immediate_gets from v$latch where name='cache buffers chains';
commit;
--exec dbms_workload_repository.create_snapshot(); 
exec pkg_test_block_size.p_exec_2k_job;
--exec dbms_workload_repository.create_snapshot();
insert into test_latch select '2k',2,gets,misses,sleeps,immediate_gets from v$latch where name='cache buffers chains';
commit;
--测试结束
exec pkg_test_block_size.p_remove_job;    
--@?/rdbms/admin/awrrpt.sql


--测试2.
delete from test_latch  where block_size='4k';
insert into test_latch select '4k',1,gets,misses,sleeps,immediate_gets from v$latch where name='cache buffers chains';
commit;
--exec dbms_workload_repository.create_snapshot();
exec pkg_test_block_size.p_exec_4k_job;
--exec dbms_workload_repository.create_snapshot();
insert into test_latch select '4k',2,gets,misses,sleeps,immediate_gets from v$latch where name='cache buffers chains';
commit;
--测试结束
exec pkg_test_block_size.p_remove_job;   
--@?/rdbms/admin/awrrpt.sql


--测试3.
delete from test_latch  where block_size='8k';
insert into test_latch select '8k',1,gets,misses,sleeps,immediate_gets from v$latch where name='cache buffers chains';
commit;
--exec dbms_workload_repository.create_snapshot();
exec pkg_test_block_size.p_exec_8k_job;
--exec dbms_workload_repository.create_snapshot();
insert into test_latch select '8k',2,gets,misses,sleeps,immediate_gets from v$latch where name='cache buffers chains';
commit;
--测试结束
exec pkg_test_block_size.p_remove_job;   
--@?/rdbms/admin/awrrpt.sql


--测试4.
delete from test_latch  where block_size='16k';
insert into test_latch select '16k',1,gets,misses,sleeps,immediate_gets from v$latch where name='cache buffers chains';
commit;
--exec dbms_workload_repository.create_snapshot();
exec pkg_test_block_size.p_exec_16k_job;
--exec dbms_workload_repository.create_snapshot();
insert into test_latch select '16k',2,gets,misses,sleeps,immediate_gets from v$latch where name='cache buffers chains';
commit;
--测试结束
exec pkg_test_block_size.p_remove_job;   
--@?/rdbms/admin/awrrpt.sql



SELECT WHAT, INTERVAL, JOB, NEXT_DATE, NEXT_SEC, FAILURES, BROKEN FROM USER_JOBS WHERE INTERVAL = 'SYSDATE+1/1440';
                                                                                            
select * from v$latch_children where name='cache buffers chains'

select * from test_latch;

--以下结果仅供参考,实际执行情况可能由于数据量不够大,并发不够大,而有差异。

select block_size,
       misses - lag_misses
  from (select t.*,lag(misses) over(partition by block_size order by misses) lag_misses
          from test_latch t) k
 where k.lag_misses is not null;


BLOCK_SIZE  MISSES-LAG_MISSES
---------- ------------------
2k              0
4k            47407
8k            67769
16k           86871


观察:
select t.*, s.sid, s.serial#, s.machine, s.program, s.osuser
  from (select c.USERNAME,
               a.event,
               a.cnt as "TIME(SECOND)",
               a.sql_id,
               b.sql_fulltext
          from (select rownum rn, t.*
                  from (select decode(s.session_state,
                                      'WAITING',
                                      s.event,
                                      'Cpu + Wait For Cpu') Event,
                               s.sql_id,
                               s.user_id,
                               count(*) CNT
                          from v$active_session_history s
                         where sample_time > sysdate - 15 / 1440
                         group by s.user_id,
                                  decode(s.session_state,
                                         'WAITING',
                                         s.event,
                                         'Cpu + Wait For Cpu'),
                                  s.sql_id
                         order by CNT desc) t
                 where rownum < 20) a,
               v$sqlarea b,
               dba_users c
         where a.sql_id = b.sql_id
           and a.user_id = c.user_id
         order by CNT desc) t,
       v$session s
 where t.sql_id = s.sql_id(+);

  

猜你喜欢

转载自www.cnblogs.com/sunliyuan/p/11877742.html