gdufo

 

学习动态性能表 第七篇--V$PROCESS 2007.5.30

     摘要:   本视图包含当前系统oracle运行的所有进程信息。常被用于将oracle或服务进程的操作系统进程ID与数据库session之间建立联系。在某些情况下非常有用:   1.         如果数据库瓶颈是系统资源(如:cpu,内存),并且占用资源最多的用户总是停留在某几个服务进程,那么进行如...  阅读全文

posted @ 2009-11-17 14:31 gdufo| 编辑 收藏

学习动态性能表 第六篇-(1)-V$SESSION_WAIT 2007.5.30

     摘要:   这是一个寻找性能瓶颈的关键视图。它提供了任何情况下session在数据库中当前正在等待什么(如果session当前什么也没在做,则显示它最后的等待事件)。当系统存在性能问题时,本视图可以做为一个起点指明探寻问题的方向。     V$SESSION_WAIT中,每一个连接到实例的session都对应一条记录。   V$SESSION_WAIT中的常用列 ...  阅读全文

posted @ 2009-11-17 14:28 gdufo| 编辑 收藏

学习动态性能表 第五篇--V$SESSION 2007.5.29

 

 在本视图中,每一个连接到数据库实例中的session都拥有一条记录。包括用户session及后台进程如DBWRLGWRarcchiver等等。

 

V$SESSION中的常用列

 

V$SESSION是基础信息视图,用于找寻用户SIDSADDR。不过,它也有一些列会动态的变化,可用于检查用户。如例:

SQL_HASH_VALUESQL_ADDRESS:这两列用于鉴别默认被session执行的SQL语句。如果为null0,那就说明这个session没有执行任何SQL语句。PREV_HASH_VALUEPREV_ADDRESS两列用来鉴别被session执行的上一条语句。

 

注意:当使用SQL*Plus进行选择时,确认你重定义的列宽不小于11以便看到完整的数值。

 

STATUS:这列用来判断session状态是:

l         Achtive:正执行SQL语句(waiting for/using a resource)

l         Inactive:等待操作(即等待需要执行的SQL语句)

l         Killed:被标注为删除

 

下列各列提供session的信息,可被用于当一个或多个combination未知时找到session

 

Session信息

l         SIDSESSION标识,常用于连接其它列

l         SERIAL#:如果某个SID又被其它的session使用的话则此数值自增加(当一个        SESSION结束,另一个SESSION开始并使用了同一个SID)

l         AUDSID:审查session ID唯一性,确认它通常也用于当寻找并行查询模式

l         USERNAME:当前sessionoracle中的用户名。

 

Client信息

数据库session被一个运行在数据库服务器上或从中间服务器甚至桌面通过SQL*Net连接到数据库的客户端进程启动,下列各列提供这个客户端的信息

l         OSUSER:客户端操作系统用户名

l         MACHINE:客户端执行的机器

l         TERMINAL:客户端运行的终端

l         PROCESS:客户端进程的ID

l         PROGRAM:客户端执行的客户端程序

要显示用户所连接PC TERMINALOSUSER,需在该PCORACLE.INIWindows中设置关键字TERMINALUSERNAME

 

Application信息

调用DBMS_APPLICATION_INFO包以设置一些信息区分用户。这将显示下列各列。

l         CLIENT_INFODBMS_APPLICATION_INFO中设置

l         ACTIONDBMS_APPLICATION_INFO中设置

l         MODULEDBMS_APPLICATION_INFO中设置

下列V$SESSION列同样可能会被用到:

l         ROW_WAIT_OBJ#

l         ROW_WAIT_FILE#

l         ROW_WAIT_BLOCK#

l         ROW_WAIT_ROW#

 

V$SESSION中的连接列

 

Column                                                            View                                               Joined Column(s)

SID             V$SESSION_WAIT,,V$SESSTAT,,V$LOCK,V$SESSION_EVENT,V$OPEN_CURSOR                 SID

(SQL_HASH_VALUE, SQL_ADDRESS)                  V$SQLTEXT, V$SQLAREA, V$SQL    (HASH_VALUE, ADDRESS)

(PREV_HASH_VALUE, PREV_SQL_ADDRESS)     V$SQLTEXT, V$SQLAREA, V$SQL    (HASH_VALUE, ADDRESS)

TADDR                                                             V$TRANSACTION                                    ADDR

PADDR                                                              V$PROCESS                                             ADDR

 

 

示例:

1.查找你的session信息

SELECT SID, OSUSER, USERNAME, MACHINE, PROCESS

  FROM V$SESSION WHERE audsid = userenv('SESSIONID');

 

2.machine已知的情况下查找session

SELECT SID, OSUSER, USERNAME, MACHINE, TERMINAL

  FROM V$SESSION

 WHERE terminal = 'pts/tl' AND machine = 'rgmdbs1';

 

3.查找当前被某个指定session正在运行的sql语句。假设sessionID100

select b.sql_text

  from v$session a,v$sqlarea b

  where a.sql_hash_value=b.hash_value and a.sid=100

寻找被指定session执行的SQL语句是一个公共需求,如果session是瓶颈的主要原因,那根据其当前在执行的语句可以查看session在做些什么。

 

posted @ 2009-11-17 11:53 gdufo| 编辑 收藏

学习动态性能表 第四篇-(1)-V$SQLTEXT 2007.5.29

 

本视图包括Shared poolSQL语句的完整文本,一条SQL语句可能分成多个块被保存于多个记录内。

  注:V$SQLAREA只包括头1000个字符。

 

V$SQLTEXT中的常用列

 

l         HASH_VALUESQL语句的Hash

l         ADDRESSsql语句在SGA中的地址

l         SQL_TEXTSQL文本。

l         PIECESQL语句块的序号

 

V$SQLTEXT中的连接列

Column                                          View                                     Joined Column(s)

HASH_VALUE, ADDRESS          V$SQL, V$SESSION            HASH_VALUE, ADDRESS

HASH_VALUE. ADDRESS          V$SESSION                          SQL_HASH_VALUE, SQL_ADDRESS

 

示例:已知hash_value:3111103299,查询sql语句:

select * from v$sqltext

where hash_value='3111103299'

order by piece

 

 

第四篇-(2)-V$SQLAREA  2007.5.29

 

  本视图持续跟踪所有shared pool中的共享cursor,在shared pool中的每一条SQL语句都对应一列。本视图在分析SQL语句资源使用方面非常重要。

 

V$SQLAREA中的信息列

 

l         HASH_VALUESQL语句的Hash值。

l         ADDRESSSQL语句在SGA中的地址。

这两列被用于鉴别SQL语句,有时,两条不同的语句可能hash值相同。这时候,必须连同ADDRESS一同使用来确认SQL语句。

l         PARSING_USER_ID:为语句解析第一条CURSOR的用户

l         VERSION_COUNT:语句cursor的数量

l         KEPT_VERSIONS

l         SHARABLE_MEMORYcursor使用的共享内存总数

l         PERSISTENT_MEMORYcursor使用的常驻内存总数

l         RUNTIME_MEMORYcursor使用的运行时内存总数。

l         SQL_TEXTSQL语句的文本(最大只能保存该语句的前1000个字符)。

l         MODULE,ACTION:使用了DBMS_APPLICATION_INFOsession解析第一条cursor时的信息

 

V$SQLAREA中的其它常用列

 

l         SORTS: 语句的排序数

l         CPU_TIME: 语句被解析和执行的CPU时间

l         ELAPSED_TIME: 语句被解析和执行的共用时间

l         PARSE_CALLS: 语句的解析调用(软、硬)次数

l         EXECUTIONS: 语句的执行次数

l         INVALIDATIONS: 语句的cursor失效次数

l         LOADS: 语句载入(载出)数量

l         ROWS_PROCESSED: 语句返回的列总数

 

V$SQLAREA中的连接列

Column                                          View                                                                Joined Column(s)

HASH_VALUE, ADDRESS          V$SESSION                                                     SQL_HASH_VALUE, SQL_ADDRESS

HASH_VALUE, ADDRESS          V$SQLTEXT, V$SQL, V$OPEN_CURSOR   HASH_VALUE, ADDRESS

SQL_TEXT                                   V$DB_OBJECT_CACHE                               NAME

 

示例:

1.查看消耗资源最多的SQL

SELECT hash_value, executions, buffer_gets, disk_reads, parse_calls

  FROM V$SQLAREA

 WHERE buffer_gets > 10000000 OR disk_reads > 1000000

 ORDER BY buffer_gets + 100 * disk_reads DESC;

 

2.查看某条SQL语句的资源消耗:

SELECT hash_value, buffer_gets, disk_reads, executions, parse_calls

  FROM V$SQLAREA

 WHERE hash_Value = 228801498 AND address = hextoraw('CBD8E4B0');

posted @ 2009-11-17 11:44 gdufo| 编辑 收藏

学习动态性能表 第三篇-(1)-v$sql 2007.5.25

     摘要:   V$SQL中存储具体的SQL语句。     一条语句可以映射多个cursor,因为对象所指的cursor可以有不同用户(如例1)。如果有多个cursor(子游标)存在,在V$SQLAREA为所有cursor提供集合信息。 例1: 这里介绍以下child cursor user A: select * from tbl user B: select * ...  阅读全文

posted @ 2009-11-17 11:42 gdufo| 编辑 收藏

学习动态性能表 第二篇--v$sesstat 2007.5.25

 

按照OracleOnlineBook中的描述,v$sesstat存储sessionloginlogout的详细资源使用统计。

 

  类似于v$sysstat,该视图存储下列类别的统计:

 

l         事件发生次数的统计,如用户提交数。

l         数据产生,存取或者操作的total(如:redo size)

l         执行操作所花费的时间累积,例如session CPU占用(如果TIMED_STATISTICS值为true)

注意:

如果初始参数STATISTICS_LEVEL被设置为TYPICALALL,时间统计被数据库自动收集如果STATISTICS_LEVEL被设置为BASIC,你必须设置TIMED_STATISTICS值为TRUE以打开收集功能。

 

如果你已设置了DB_CACHE_ADVICE,TIMED_STATISTICSTIMED_OS_STATISTICS,或在初始参数文件或使用ALTER_SYSTEMALTER SESSION,那么你所设定的值的值将覆盖STATISTICS_LEVEL的值。

 

v$sysstatv$sesstat差别如下:

n         v$sesstat只保存session数据,而v$sysstat则保存所有sessions的累积值。

n         v$sesstat只是暂存数据,session退出后数据即清空。v$sysstat则是累积的,只有当实例被shutdown才会清空。

n         v$sesstat不包括统计项名称,如果要获得统计项名称则必须与v$sysstatv$statname连接查询获得。

 

v$sesstat可被用于找出如下类型session

n         高资源占用

n         高平均资源占用比(登陆后资源使用率)

n         默认资源占用比(两快照之间)

 

V$SESSTAT中使用统计

  多数v$sesstat中的统计参考是v$sysstat描述的子集,包括session logical reads, CPU used by this session, db block changes, redo size, physical writes, parse count (hard), parse count (total), sorts (memory), and sorts (disk).

 

V$SESSTAT常用列说明

n         SIDsession唯一ID

n         STATISTIC#:资源唯一ID

n         VALUE:资源使用

 

 

示例1:下列找出当前session中最高的logicalPhysical I/O比率.

 

  下列SQL语句显示了所有连接到数据库的session逻辑、物理读比率(每秒)logicalphysical I/O比率是通过自登陆后的时间消耗计算得出。对于sessions连接到数据库这种长周期操作而言也许不够精确,不过做个示例却足够了。

 

先获得session逻辑读和物理读统计项的STATISTIC#值:

SELECT name, statistic#

  FROM V$STATNAME

  WHERE name IN ('session logical reads','physical reads') ;

NAME                           STATISTIC#

------------------------------ ----------

session logical reads                   9

physical reads                         40

 

通过上面获得的STATISTIC#值执行下列语句:

 

SELECT ses.sid

     , DECODE(ses.action,NULL,'online','batch')          "User"

     , MAX(DECODE(sta.statistic#,9,sta.value,0))

       /greatest(3600*24*(sysdate-ses.logon_time),1)     "Log IO/s"

     , MAX(DECODE(sta.statistic#,40,sta.value,0))

       /greatest(3600*24*(sysdate-ses.logon_time),1)     "Phy IO/s"

     , 60*24*(sysdate-ses.logon_time)                    "Minutes"

 FROM V$SESSION ses

    , V$SESSTAT sta

WHERE ses.status     = 'ACTIVE'

  AND sta.sid        = ses.sid

  AND sta.statistic# IN (9,40)

GROUP BY ses.sid, ses.action, ses.logon_time

ORDER BY

        SUM( DECODE(sta.statistic#,40,100*sta.value,sta.value) )

      / greatest(3600*24*(sysdate-ses.logon_time),1)  DESC;

 

  SID User   Log IO/s Phy IO/s Minutes

----- ------ -------- -------- -------

 1951 batch       291    257.3       1

  470 online    6,161     62.9       0

  730 batch     7,568     43.2     197

 2153 online    1,482     98.9      10

 2386 batch     7,620     35.6      35

 1815 batch     7,503     35.5      26

 1965 online    4,879     42.9      19

 1668 online    4,318     44.5       1

 1142 online      955     69.2      35

 1855 batch       573     70.5       8

 1971 online    1,138     56.6       1

 1323 online    3,263     32.4       5

 1479 batch     2,857     35.1       3

  421 online    1,322     46.8      15

 2405 online      258     50.4       8

 

 

示例2:又例如通过v$sesstatv$statname连接查询某个SID各项信息。

select a.*,b.name

  from v$sesstat a,v$statname b

  where a.sid=10 and a.statistic#=b.statistic#;

posted @ 2009-11-17 11:40 gdufo| 编辑 收藏

学习动态性能表 第一篇--v$sysstat 2007.5.23

转自网络

 

 按照OracleDocument中的描述,v$sysstat存储自数据库实例运行那刻起就开始累计全实例(instance-wide)的资源使用情况。

类似于v$sesstat,该视图存储下列的统计信息:

1>.事件发生次数的统计(如:user commits)

2>.数据产生,存取或者操作的total(如:redo size)

3>.如果TIMED_STATISTICS值为true,则统计花费在执行操作上的总时间(如:CPU used by this session)

v$sysstat视图常用列介绍:

l         STATISTIC#: 标识

l         NAME: 统计项名称

l         VALUE: 资源使用量

该视图还有一列class-统计类别但极少会被使用,各类信息如下:

1 代表事例活动

2 代表Redo buffer活动

4 代表锁

8 代表数据缓冲活动

16 代表OS活动

32 代表并行活动

64 代表表访问

128 代表调试信息

注意:Statistic#的值在不同版本中各不相同,使用时要用Name做为查询条件而不要以statistic#的值做为条件。

使用v$sysstat中的数据

  该视图中数据常被用于监控系统性能。如buffer cache命中率、软解析率等都可从该视图数据计算得出。

  该视图中的数据也被用于监控系统资源使用情况,以及系统资源利用率的变化。正因如此多的性能数据,检查某区间内系统资源使用情况可以这样做,在一个时间段开始时创建一个视图数据快照,结束时再创建一个,二者之间各统计项值的不同(end value - begin value)即是这一时间段内的资源消耗情况。这是oracle工具的常用方法,诸如Statspack以及BSTAT/ESTAT都是如此。

  为了对比某个区间段的数据,源数据可以被格式化(每次事务,每次执行,每秒钟或每次登陆),格式化后数据更容易从两者中鉴别出差异。这类的对比在升级前,升级后或仅仅想看看一段时间内用户数量增长或数据增加如何影响资源使用方面更加实用。

  你也可以使用v$sysstat数据通过查询v$system_event视图来检查资源消耗和资源回收。

V$SYSSTAT中的常用统计

  V$SYSSTAT中包含多个统计项,这部分介绍了一些关键的v$sysstat统计项,在调优方面相当有用。下列按字母先后排序:

数据库使用状态的一些关键指标:

l         CPU used by this session:所有sessioncpu占用量,不包括后台进程。这项统计的单位是百分之x.完全调用一次不超过10ms

l         db block changes:那部分造成SGA中数据块变化的insert,updatedelete操作数 这项统计可以大概看出整体数据库状态。在各项事务级别,这项统计指出脏缓存比率。

l         execute count:执行的sql语句数量(包括递归sql)

l         logons current:当前连接到实例的Sessions。如果当前有两个快照则取平均值。

l         logons cumulative:自实例启动后的总登陆次数。

l         parse count (hard):在shared pool中解析调用的未命中次数。当sql语句执行并且该语句不在shared pool或虽然在shared pool但因为两者存在部分差异而不能被使用时产生硬解析。如果一条sql语句原文与当前存在的相同,但查询表不同则认为它们是两条不同语句,则硬解析即会发生。硬解析会带来cpu和资源使用的高昂开销,因为它需要oracleshared pool中重新分配内存,然后再确定执行计划,最终语句才会被执行。

l         parse count (total):解析调用总数,包括软解析和硬解析。当session执行了一条sql语句,该语句已经存在于shared pool并且可以被使用则产生软解析。当语句被使用(即共享) 所有数据相关的现有sql语句(如最优化的执行计划)必须同样适用于当前的声明。这两项统计可被用于计算软解析命中率。

l         parse time cpu:总cpu解析时间(单位:10ms)。包括硬解析和软解析。

l         parse time elapsed:完成解析调用的总时间花费。

l         physical readsOS blocks read数。包括插入到SGA缓存区的物理读以及PGA中的直读这项统计并非i/o请求数。

l         physical writes:从SGA缓存区被DBWR写到磁盘的数据块以及PGA进程直写的数据块数量。

l         redo log space requests:在redo logs中服务进程的等待空间,表示需要更长时间的log switch

l         redo sizeredo发生的总次数(以及因此写入log buffer),以byte为单位。这项统计显示出update活跃性。

l         session logical reads:逻辑读请求数。

l         sorts (memory) and sorts (disk)sorts(memory)是适于在SORT_AREA_SIZE(因此不需要在磁盘进行排序)的排序操作的数量。sorts(disk)则是由于排序所需空间太大,SORT_AREA_SIZE不能满足而不得不在磁盘进行排序操作的数量。这两项统计通常用于计算in-memory sort ratio

l         sorts (rows): 列排序总数。这项统计可被'sorts (total)'统计项除尽以确定每次排序的列。该项可指出数据卷和应用特征。

l         table fetch by rowid:使用ROWID返回的总列数(由于索引访问或sql语句中使用了'where rowid=&rowid'而产生)

l         table scans (rows gotten):全表扫描中读取的总列数

l         table scans (blocks gotten):全表扫描中读取的总块数,不包括那些split的列。

l         user commits + user rollbacks:系统事务起用次数。当需要计算其它统计中每项事务比率时该项可以被做为除数。例如,计算事务中逻辑读,可以使用下列公式:session logical reads / (user commits + user rollbacks)

注:SQL语句的解析有软解析soft parse与硬解析hard parse之说,以下是5个步骤:

1:语法是否合法(sql写法)

2:语义是否合法(权限,对象是否存在)

3:检查该sql是否在公享池中存在

-- 如果存在,直接跳过45,运行sql. 此时算soft parse

4:选择执行计划

5:产生执行计划

-- 如果5个步骤全做,这就叫hard parse.

注意物理I/O

  oracle报告物理读也许并未导致实际物理磁盘I/O操作。这完全有可能因为多数操作系统都有缓存文件,可能是那些块在被读取。块也可能存于磁盘或控制级缓存以再次避免实际I/OOracle报告有物理读也许仅仅表示被请求的块并不在缓存中。

V$SYSSTAT得出实例效率比(Instance Efficiency Ratios)

下列是些典型的instance efficiency ratios v$sysstat数据计算得来,每项比率值应该尽可能接近1

l         Buffer cache hit ratio:该项显示buffer cache大小是否合适。

公式:1-((physical reads-physical reads direct-physical reads direct (lob)) / session logical reads)

执行:

select1-((a.value-b.value-c.value)/d.value)

 from v$sysstat a,v$sysstat b,v$sysstat c,v$sysstat d

 where a.name='physical reads'and

         b.name='physical reads direct'and

         c.name='physical reads direct (lob)'and

         d.name='session logical reads';

l         Soft parse ratio:这项将显示系统是否有太多硬解析。该值将会与原始统计数据对比以确保精确。例如,软解析率仅为0.2则表示硬解析率太高。不过,如果总解析量(parse count total)偏低,这项值可以被忽略。

公式:1 - ( parse count (hard) / parse count (total) )

执行:

select1-(a.value/b.value)

 from v$sysstat a,v$sysstat b

 Wherea.name='parse count (hard)'and b.name='parse count (total)';

l         In-memory sort ratio:该项显示内存中完成的排序所占比例。最理想状态下,在OLTP系统中,大部分排序不仅小并且能够完全在内存里完成排序。

公式:sorts (memory) / ( sorts (memory) + sorts (disk) )

执行:

select a.value/(b.value+c.value)

 from v$sysstat a,v$sysstat b,v$sysstat c

 wherea.name='sorts (memory)'and

         b.name='sorts (memory)'andc.name='sorts (disk)';

l         Parse to execute ratio:在生产环境,最理想状态是一条sql语句一次解析多数运行。

公式:1 - (parse count/execute count)

执行:

select1-(a.value/b.value)

 from v$sysstat a,v$sysstat b

 where a.name='parse count (total)'and b.name='execute count';

l         Parse CPU to total CPU ratio:该项显示总的CPU花费在执行及解析上的比率。如果这项比率较低,说明系统执行了太多的解析。

公式:1 - (parse time cpu / CPU used by this session)

执行:

select1-(a.value/b.value)

 from v$sysstat a,v$sysstat b

 where a.name='parse time cpu'and

         b.name='CPU used by this session';

l         Parse time CPU to parse time elapsed:通常,该项显示锁竞争比率。这项比率计算

是否时间花费在解析分配给CPU进行周期运算(即生产工作)。解析时间花费不在CPU周期运算通常表示由于锁竞争导致了时间花费

公式:parse time cpu / parse time elapsed

执行:

select a.value/b.value

 from v$sysstat a,v$sysstat b

 where a.name='parse time cpu'and b.name='parse time elapsed';

V$SYSSTAT获取负载间档(Load Profile)数据

  负载间档是监控系统吞吐量和负载变化的重要部分,该部分提供如下每秒和每个事务的统计信息:logons cumulative, parse count (total), parse count (hard), executes, physical reads, physical writes, block changes, and redo size.

  被格式化的数据可检查'rates'是否过高,或用于对比其它基线数据设置为识别system profile在期间如何变化。例如,计算每个事务中block changes可用如下公式:

db block changes / ( user commits + user rollbacks )

执行:

select a.value/(b.value+c.value)

 from v$sysstat a,v$sysstat b,v$sysstat c

 where a.name='db block changes'and

         b.name='user commits'andc.name='user rollbacks';

其它计算统计以衡量负载方式,如下:

l         Blocks changed for each read:这项显示出block changesblock reads中的比例。它将指出是否系统主要用于只读访问或是主要进行诸多数据操作(如:inserts/updates/deletes)

公式:db block changes / session logical reads

执行:

select a.value/b.value

 from v$sysstat a,v$sysstat b

 where a.name='db block changes'and

         b.name='session logical reads' ;

l         Rows for each sort

公式:sorts (rows) / ( sorts (memory) + sorts (disk) )

执行:

select a.value/(b.value+c.value)

 from v$sysstat a,v$sysstat b,v$sysstat c

 where a.name='sorts (rows)'and

         b.name='sorts (memory)'andc.name='sorts (disk)';

posted @ 2009-11-17 11:38 gdufo 阅读(122) | 评论 (0)编辑 收藏

SQL_TRACE及 Tkprof用法以及问题分析

ORACLE中SQL TRACE和TKPROF的使用
SQL TRACE 和 tkprof sql语句分析工具

一 SQL TRACE 使用方法:
1.初始化sql trace
参数:
timed_statistics=true 允许sql trace 和其他的一些动态性能视图收集与时间有关的参数、
SQL>alter session set titimed_statistics=true
max_dump_file_size=500 指定跟踪文件的大小
SQL> alter system set max_dump_file_size=500;
user_dump_dest 指定跟踪文件的路径
SQL> alter system set user_dump_dest=/oracle/oracle/diag/rdbms/orcl/orcl/trace;

2.为一个session 启动sql trace

2.1命令方式
alter session set sql_trace=true
2.2 通过存储过程启动sqltrace
select sid,serial#,osuser from v$session;
SID SERIAL# OSUSER
168 1 oracle

execute rdbms_system.set_sql_trace_in_session (168 ,1,true);
3.停止一个sql trace 会话
3.1 命令方式
alter session set sql_trace=false
3.2 储存过程的方式
execute rdbms_system.set_sql_trace_in_session (168 ,1,false);
4. 为整个实例启动SQL trace (一般消耗系统性能较高,不会用)
alter system set sql_trace=true scope=spfile
从新启动数据库
5. 停止一个实例的sql trace
alter system set sql_trace=flase scope=spfile

启动sql trace 之后收集的信息包括
1.解析、执行、返回数据的次数
2.cpu和执行命令的时间
3.物理读和逻辑读的次数
4.系统处理的记录数
5.库缓冲区错误
二 TKPROF的使用
tkprof 的目的是将sql trace 生成的跟踪文件转换成用户可以理解的格式
1. 格式
tkprof inputfile outputfile [optional | parameters ]
参数和选项:
explain=user/password 执行explain命令将结果放在SQL trace的输出文件中
table=schema.table 指定tkprof处理sql trace文件时临时表的模式名和表名
insert=scriptfile 创建一个文件名为scriptfile的文件,包含了tkprof存放的输出sql语句
sys=[yes/no] 确定系统是否列出由sys用户产生或重调的sql语句
print=number 将仅生成排序后的第一条sql语句的输出结果
record=recordfile 这个选项创建一个名为recorderfile的文件,包含了所有重调用的sql语句
sort=sort_option 按照指定的方法对sql trace的输出文件进行降序排序
sort_option 选项
prscnt 按解析次数排序
prscpu 按解析所花cpu时间排序
prsela 按解析所经历的时间排序
prsdsk 按解析时物理的读操作的次数排序
prsqry 按解析时以一致模式读取数据块的次数排序
prscu 按解析时以当前读取数据块的次数进行排序
execnt 按执行次数排序
execpu 按执行时花的cpu时间排序
exeela 按执行所经历的时间排序
exedsk 按执行时物理读操作的次数排序
exeqry 按执行时以一致模式读取数据块的次数排序
execu 按执行时以当前模式读取数据块的次数排序
exerow 按执行时处理的记录的次数进行排序
exemis 按执行时库缓冲区的错误排序
fchcnt 按返回数据的次数进行排序
fchcpu 按返回数据cpu所花时间排序
fchela 按返回数据所经历的时间排序
fchdsk 按返回数据时的物理读操作的次数排序
fchqry 按返回数据时一致模式读取数据块的次数排序
fchcu 按返回数据时当前模式读取数据块的次数排序
fchrow 按返回数据时处理的数据数量排序
三 sql trace 的输出结果
count:提供OCI过程的执行次数
CPU: 提供执行CPU所花的时间单位是秒
Elapsed:提供了执行时所花的时间。单位是秒。这个参数值等于用户响应时间
Disk:提供缓存区从磁盘读取的次数
Query:以一致性模式从缓存区获得数据的次数
Current:以当前模式从缓存区获得数据的次数
ROWs: 返回调用或执行调用时,处理的数据行的数量。

在report.txt文件头有各个数据的解释,根据以下一些指标可以分析一下SQL的执行性能: query+current/rows 平均每行所需的block数,太大的话(超过20)SQL语句效率太低
Parse count/Execute count parse count应尽量接近1,如果太高的话,SQL会进行不必要的reparse。要检查Pro*C程序的MAXOPENCURSORS是不是太低了,或不适当的使用的RELEASE_CURSOR选项
rows Fetch/Fetch Fetch Array的大小,太小的话就没有充分利用批量Fetch的功能,增加了数据在客户端和服务器之间的往返次数。在Pro*C中可以用prefetch=NN,Java/JDBC中可调用SETROWPREFETCH,在PL/SQL中可以用BULK COLLECT,SQLPLUS中的arraysize(缺省是15)
disk/query+current 磁盘IO所占逻辑IO的比例,太大的话有可能是db_buffer_size过小(也跟SQL的具体特性有关)
elapsed/cpu 太大表示执行过程中花费了大量的时间等待某种资源
cpu OR elapsed 太大表示执行时间过长,或消耗了大量的CPU时间,应该考虑优化
执行计划中的Rows 表示在该处理阶段所访问的行数,要尽量减少


四:举例:
sql>alter session set sql_trace=true
SQL>select * from dba_users;
SQL>show parameter user_dump_dest
user_dump_dest string /oracle/oracle/diag/rdbms/orcl/orcl/trace
SQL>exit
cd /oracle/oracle/diag/rdbms/orcl/orcl/trace
tkprof orcl_ora_11066.trc /oracle/oracle/trace1.out sys=yes

vi trace.out

1. query+current/rows 平均每行所需的block数,太大的话(超过20)SQL语句效率太低
2. Parse count/Execute count parse count应尽量接近1,如果太高的话,SQL会进行不必要的reparse。
要检查Pro*C程序的MAXOPENCURSORS是不是太低了,或不适当的使用的RELEASE_CURSOR选项
3. rows Fetch/Fetch Fetch Array的大小,太小的话就没有充分利用批量Fetch的功能,
增加了数据在客户端和服务器之间的往返次数。在Pro*C中可以用prefetch=NN,Java/JDBC中可调用SETROWPREFETCH,
在PL/SQL中可以用BULK COLLECT,SQLPLUS中的arraysize(缺省是15)  
4. disk/query+current 磁盘IO所占逻辑IO的比例,太大的话有可能是db_buffer_size过小(也跟SQL的具体特性有关)  
5. elapsed/cpu 太大表示执行过程中花费了大量的时间等待某种资源  
6. cpu OR elapsed 太大表示执行时间过长,或消耗了大量的CPU时间,应该考虑优化
7. 执行计划中的Rows 表示在该处理阶段所访问的行数,要尽量

posted @ 2009-11-16 19:39 gdufo 阅读(1137) | 评论 (0)编辑 收藏

oracle大表分区的一点点心得

http://www.knowsky.com/388420.html

最近在做一个客户关系治理系统,项目做的到不是非常成功,可还是学到了不少的知识,由于数据量很大,没有专门的Oracle数据库人员支持,对数据库优化治理等也只有我这个约懂一点的人上了。在对数据库优化上有一点点心得写出来希望能同大家一起学习和交流。

数据库大表的优化:采用蔟表(clustered tables)及蔟索引(Clustered Index)
蔟表和蔟索引是oracle所提供的一种技术,其基本思想是将几张具有相同数据项、 并且经常性一起使用的表通过共享数据块(data block)的模式存放在一起。各表间的共同字段作为蔟键值(cluster key),数据库在访问数据时,首先找到蔟键值,以此同时获得若干张表的相关数据。蔟表所能带来的好处是可以减少I/O和减少存储空间,其中我更看重前 者。采用表分区(partition)
表分区技术是在超大型数据库(VLDB)中将大表及其索引通过分区(patition)的形式分割为若干较小、可治理的小块,并且每一分区可 进一步划分为更小的子分区(sub partition)。而这种分区对于应用来说是透明的。通过对表进行分区,可以获得以下的好处:
1)减少数据损坏的可能性。
2)各分区可以独立备份和恢复,增强了数据库的可治理性。
3)可以控制分区在硬盘上的分布,以均衡IO,改善了数据库的性能。
蔟表与表分区技术的侧重点各有不同,前者侧重于改进关联表间查询的效率,而表分区侧重于大表的可治理性及局部查询的性能。而这两项对于我的系统来说都是极为重要。由于本人技术限制,目前尚不确定两者是否可以同时实现,有那位在这方面有经验的给点指导将不胜感激。 
在两者无法同时实现的情况下,应依照需实现的功能有所取舍。综合两种模式的优缺点,我认为采用表分区技术较为适用于我们的应用。
Oracle的表分区有以下几种类型:
1)范围分区:将表按某一字段或若干个字段的取值范围分区。
2)hash分区:将表按某一字段的值均匀地分布到若干个指定的分区。
3)复合分区:结合了前面两种分区类型的优点,首先通过值范围将表进行分区,然后以hash模式将数据进一步均匀分配至物理存储位置。
综合考虑各项因素,以第三种类型最为优越。(本人实在技术有限仅采用了第1种范围分区,因为比较简单,便于治理)
优化的具体步骤:
1.确定需要优化分区的表:
经过对系统数据库表结构和字段,应用程序的分析,现在确定那些大表需要进行分区:
如帐户交易明细表acct_detail.
2.确定表分区的方法和分区键:
分区类型:采用范围分区。
分 区 键:
按trans_date(交易时间)字段进行范围分区.
3.确定分区键的分区范围,及打算分多少分区:
如:帐户交易明细表acct_detail.
根据字段(trans_date)分成一下分区:
1).分区1:09/01/2003   
2).分区2:10/01/2003   
3).分区3:11/01/2003   
4).分区4:12/01/2003   
5).分区5:01/01/2004 
6).分区6:02/01/2004 
   该表明显需要在以后增加分区。
4.建立分区表空间和分区索引空间
  1).建立表的各个分区的表空间: 
   1.分区1:crm_detail_200309
   CREATE TABLESPACE crm_detail_200309  DATAFILE  
   ‘/u1/oradata/orcl/crm_detail_20030901.dbf’ 
   SIZE 2000M EXTENT MANAGEMENT LOCAL UNIFORM size 16M;
   其它月份以后同以上(我在此采用oracle的表空间本地治理的方法)。

  2). 建立分区索引表空间
   1.分区1:index_detail_200309
   CREATE TABLESPACE index_detail_200309  DATAFILE  
   ‘/u3/oradata/orcl/index_detail_20030901.dbf’ 
   SIZE 2000M  EXTENT MANAGEMENT LOCAL UNIFORM size 16M;
5.建立基于分区的表:
   create  table  table name
   (

    ........
    )
    enable row movment               --此语句是能修改行分区键值,也就是如不添加该                                     句不能修改记录的分区键值,不能使记录分区迁移
    PARTITION   BY   RANGE  (TRANS_DATE)
    (
       PARTITION     crm_detail_200309  VALUES  LESS THAN 
(TO_DATE (‘09/01/2003’,’mm/dd/yyyy’ ) )
TABLESPACE   crm_detail_200309,
       其他分区.....
     );
6.建立基于分区的索引:
  create  index   index_name  on table_name (分区键+…)
   global                                  --这里是全局分区索引,也可以建本地索引
   PARTITION   BY   RANGE  (TRANS_DATE)
   (
     PARTITION     index_detail_200309  VALUES  LESS THAN 
     (TO_DATE ('09/01/2003','mm/dd/yyyy' )) 
     TABLESPACE   index_detail_200309,
     其他索引分区...
    );
   
对表的分区就这样完成了,第一次主要确定表分区的分区策约是最重要的,可我觉得对表分区难在以后对表分区的治理上面,因为随着数据量的增加,表分 区必然存在删除,扩容,增加等。在这些过程中还牵涉到全局等索引,因为对分区表进行ddl操作为破坏全局索引,故全局索引必须在ddl后要重 rebuild.

以上写的很乱也很差,希望大家多多谅解和指点。

posted @ 2009-11-15 10:25 gdufo 阅读(1667) | 评论 (1)编辑 收藏

oracle分区表总结(转)

http://m77m78.itpub.net/post/125/280787


ORACLE里如果遇到特别大的表,可以使用分区的表来改变其应用程序的性能。


同事的分区表总结,转载一下。

1.1分区表PARTITION table

ORACLE里如果遇到特别大的表,可以使用分区的表来改变其应用程序的性能。

1.1.1分区表的建立:

某公司的每年产生巨大的销售记录,DBA向公司建议每季度的数据放在一个分区内,以下示范的是该公司1999年的数据(假设每月产生30M的数据),操作如下:

范围分区表:

CREATE TABLE sales

(invoice_no NUMBER,

...

sale_date DATE NOT NULL )

PARTITION BY RANGE (sale_date)

(PARTITION sales1999_q1

VALUES LESS THAN (TO_DATE(‘1999-04-01’,’YYYY-MM-DD’)

TABLESPACE ts_sale1999q1,

PARTITION sales1999_q2

VALUES LESS THAN (TO_DATE(‘1999-07-01’,’YYYY-MM-DD’)

TABLESPACE ts_sale1999q2,

PARTITION sales1999_q3

VALUES LESS THAN (TO_DATE(‘1999-10-01’,’YYYY-MM-DD’)

TABLESPACE ts_sale1999q3,

PARTITION sales1999_q4

VALUES LESS THAN (TO_DATE(‘2000-01-01’,’YYYY-MM-DD’)

TABLESPACE ts_sale1999q4 );

--values less than (maxvalue)

列表分区表:

create table emp (

empno number(4),

ename varchar2(30),

location varchar2(30))

partition by list (location)

(partition p1 values ('北京'),

partition p2 values ('上海','天津','重庆'),

partition p3 values ('广东','福建')

partition p0 values (default)

);

哈希分区:

create table emp (

empno number(4),

ename varchar2(30),

sal number)

partition by hash (empno)

partitions 8

store in (emp1,emp2,emp3,emp4,emp5,emp6,emp7,emp8);

组合分区:

范围哈希组合分区:

create table emp (

empno number(4),

ename varchar2(30),

hiredate date)

partition by range (hiredate)

subpartition by hash (empno)

subpartitions 2

(partition e1 values less than (to_date('20020501','YYYYMMDD')),

partition e2 values less than (to_date('20021001','YYYYMMDD')),

partition e3 values less than (maxvalue));

范围列表组合分区:

CREATE TABLE customers_part (

customer_id NUMBER(6),

cust_first_name VARCHAR2(20),

cust_last_name VARCHAR2(20),

nls_territory VARCHAR2(30),

credit_limit NUMBER(9,2))

PARTITION BY RANGE (credit_limit)

SUBPARTITION BY LIST (nls_territory)

SUBPARTITION TEMPLATE

(SUBPARTITION east VALUES ('CHINA', 'JAPAN', 'INDIA', 'THAILAND'),

SUBPARTITION west VALUES ('AMERICA', 'GERMANY', 'ITALY', 'SWITZERLAND'),

SUBPARTITION other VALUES (DEFAULT))

(PARTITION p1 VALUES LESS THAN (1000),

PARTITION p2 VALUES LESS THAN (2500),

PARTITION p3 VALUES LESS THAN (MAXVALUE));

create table t1 (id1 number,id2 number)

partition by range (id1) subpartition by list (id2)

(partition p11 values less than (11)

(subpartition subp1 values (1))

);

索引分区:

CREATE INDEX month_ix ON sales(sales_month)
GLOBAL PARTITION BY RANGE(sales_month)
(PARTITION pm1_ix VALUES LESS THAN (2)
PARTITION pm12_ix VALUES LESS THAN (MAXVALUE));

1.1.2分区表的维护:

增加分区:

ALTER TABLE sales ADD PARTITION sales2000_q1

VALUES LESS THAN (TO_DATE(‘2000-04-01’,’YYYY-MM-DD’)

TABLESPACE ts_sale2000q1;

如果已有maxvalue分区,不能增加分区,可以采取分裂分区的办法增加分区!

删除分区:

ALTER TABLE salesDROP PARTION sales1999_q1;

截短分区:

alter table sales truncate partiton sales1999_q2;

合并分区:

alter table sales merge partitons sales1999_q2, sales1999_q3 into sales1999_q23;

alter index ind_t2 rebuild partition p123 parallel 2;

分裂分区:

ALTER TABLE sales

SPLIT PARTITON sales1999_q4

AT TO_DATE (‘1999-11-01’,’YYYY-MM-DD’)

INTO (partition sales1999_q4_p1, partition sales1999_q4_p2) ;

alter table t2 split partition p123 values (1,2) into (partition p12,partition p3);

交换分区:

alter table x exchange partition p0 with table bsvcbusrundatald ;

访问指定分区:

select * from sales partition(sales1999_q2)

EXPORT指定分区:

exp sales/sales_password tables=sales:sales1999_q1

file=sales1999_q1.dmp

IMPORT指定分区:

imp sales/sales_password FILE =sales1999_q1.dmp

TABLES = (sales:sales1999_q1) IGNORE=y

查看分区信息:

user_tab_partitions, user_segments

注:若分区表跨不同表空间,做导出、导入时目标数据库必须预建这些表空间。分表区各区所在表空间在做导入时目标数据库一定要预建这些表空间!这些表空间不一定是用户的默认表空间,只要存在即可。如果有一个不存在,就会报错!

默 认时,对分区表的许多表维护操作会使全局索引不可用,标记成UNUSABLE。 那么就必须重建整个全局索引或其全部分区。如果已被分区,Oracle 允许在用于维护操作的ALTER TABLE 语句中指定UPDATE GLOBAL INDEXES 来重载这个默认特性,指定这个子句也就告诉Oracle 当它执行维护操作的DDL 语句时更新全局索引,这提供了如下好处:
1.在操作基础表的同时更新全局索引这就不需要后来单独地重建全局索引;
2.因为没有被标记成UNUSABLE, 所以全局索引的可用性更高了,甚至正在执行分区的DDL 语句时仍然可用索引来访问表中的其他分区,避免了查询所有失效的全局索引的名字以便重建它们;
另外在指定UPDATE GLOBAL INDEXES 之前还要考虑如下性能因素:
1.因为要更新事先被标记成UNUSABLE 的索引,所以分区的DDL 语句要执行更长时间,当然这要与先不更新索引而执行DDL 然后再重建索引所花的时间做个比较,一个适用的规则是如果分区的大小小于表的大小的5% ,则更新索引更快一点;
2.DROP TRUNCATE 和EXCHANGE 操作也不那么快了,同样这必须与先执行DDL 然后再重建所有全局索引所花的时间做个比较;
3.要登记对索引的更新并产生重做记录和撤消记录,重建整个索引时可选择NOLOGGING;
4.重建整个索引产生一个更有效的索引,因为这更利于使用空间,再者重建索引时允许修改存储选项。
注意分区索引结构表不支持UPDATE GLOBAL INDEXES 子句。

1.1.3普通表变为分区表

将已存在数据的普通表转变为分区表,没有办法通过修改属性的方式直接转化为分区表,必须通过重建的方式进行转变,一般可以有三种方法,视不同场景使用:

用例:

方法一:利用原表重建分区表。

CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
INSERT INTO T
SELECT ROWNUM, SYSDATE - ROWNUM FROM DBA_OBJECTS WHERE ROWNUM <=
5000
;
COMMIT;

CREATE TABLE T_NEW (ID, TIME) PARTITION BY RANGE (TIME)
(PARTITION P1 VALUES LESS THAN (TO_DATE('2000-1-1', 'YYYY-MM-DD')),
PARTITION P2 VALUES LESS THAN (TO_DATE('2002-1-1', 'YYYY-MM-DD')),
PARTITION P3 VALUES LESS THAN (TO_DATE('2005-1-1', 'YYYY-MM-DD')),
PARTITION P4 VALUES LESS THAN (MAXVALUE))
AS SELECT ID, TIME FROM T;

RENAME T TO T_OLD;

RENAME T_NEW TO T;

SELECT COUNT(*) FROM T;

COUNT(*)
----------
5000

SELECT COUNT(*) FROM T PARTITION (P1);

COUNT(*)
----------
2946

SELECT COUNT(*) FROM T PARTITION (P2);

COUNT(*)
----------
731

SELECT COUNT(*) FROM T PARTITION (P3);

COUNT(*)
----------
1096

优点:方法简单易用,由于采用DDL语句,不会产生UNDO,且只产生少量REDO,效率相对较高,而且建表完成后数据已经在分布到各个分区中了。

不足:对于数据的一致性方面还需要额外的考虑。由于几乎没有办法通过手工锁定T表的方式保证一致性,在执行CREATE TABLE语句和RENAME T_NEW TO T语句直接的修改可能会丢失,如果要保证一致性,需要在执行完语句后对数据进行检查,而这个代价是比较大的。另外在执行两个RENAME语句之间执行的对T的访问会失败。

适用于修改不频繁的表,在闲时进行操作,表的数据量不宜太大。

方法二:使用交换分区的方法。

Drop table t;
CREATE
TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
INSERT INTO T
SELECT ROWNUM, SYSDATE - ROWNUM FROM DBA_OBJECTS WHERE ROWNUM <=
5000
;
COMMIT;

CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)
(PARTITION P1 VALUES LESS THAN (TO_DATE('2005-9-1', 'YYYY-MM-DD')),
PARTITION P2 VALUES LESS THAN (MAXVALUE));

ALTER TABLE T_NEW EXCHANGE PARTITION P1 WITH TABLE T;

RENAME T TO T_OLD;

RENAME T_NEW TO T;

优点:只是对数据字典中分区和表的定义进行了修改,没有数据的修改或复制,效率最高。如果对数据在分区中的分布没有进一步要求的话,实现比较简单。在执行完RENAME操作后,可以检查T_OLD中是否存在数据,如果存在的话,直接将这些数据插入到T中,可以保证对T插入的操作不会丢失。

不足:仍然存在一致性问题,交换分区之后RENAME T_NEW TO T之前,查询、更新和删除会出现错误或访问不到数据。如果要求数据分布到多个分区中,则需要进行分区的SPLIT操作,会增加操作的复杂度,效率也会降低。

适用于包含大数据量的表转到分区表中的一个分区的操作。应尽量在闲时进行操作。

方法三:Oracle9i以上版本,利用在线重定义功能

Drop table t;
CREATE
TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
INSERT INTO T
SELECT ROWNUM, SYSDATE - ROWNUM FROM DBA_OBJECTS WHERE ROWNUM <=
5000
;
COMMIT;

EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(USER, 'T');

PL/SQL 过程已成功完成。

CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)
(PARTITION P1 VALUES LESS THAN (TO_DATE('2004-7-1', 'YYYY-MM-DD')),
PARTITION P2 VALUES LESS THAN (TO_DATE('2005-1-1', 'YYYY-MM-DD')),
PARTITION P3 VALUES LESS THAN (TO_DATE('2005-7-1', 'YYYY-MM-DD')),
PARTITION P4 VALUES LESS THAN (MAXVALUE));

表已创建。

EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER, 'T', 'T_NEW');

PL/SQL 过程已成功完成。

EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(USER, 'T', 'T_NEW');

PL/SQL 过程已成功完成。

SELECT COUNT(*) FROM T;

COUNT(*)
----------
5000

SELECT COUNT(*) FROM T PARTITION (P3);

COUNT(*)
----------
1096

优点:保证数据的一致性,在大部分时间内,表T都可以正常进行DML操作。只在切换的瞬间锁表,具有很高的可用性。这种方法具有很强的灵活性,对各种不同的需要都能满足。而且,可以在切换前进行相应的授权并建立各种约束,可以做到切换完成后不再需要任何额外的管理操作。

不足:实现上比上面两种略显复杂。

适用于各种情况。

这里只给出了在线重定义表的一个最简单的例子,详细的描述和例子可以参考下面两篇文章。

Oracle的在线重定义表功能:http://blog.itpub.net/post/468/12855

Oracle的在线重定义表功能(二):http://blog.itpub.net/post/468/12962

XSB:

把一个已存在数据的大表改成分区表:

第一种(表不是太大):

1.把原表改名:
rename xsb1 to xsb2;
2.
创建分区表:
CREATE TABLE xsb1
PARTITION BY LIST (c_test)
(PARTITION xsb1_p1 VALUES (1),
PARTITION xsb1_p2 VALUES (2),
PARTITION xsb1_p0 VALUES (default))
nologging AS SELECT * FROM xsb2;
3.
将原表上的触发器、主键、索引等应用到分区表上;
4.
删除原表:
drop table xsb2;

第二种(表很大)

1.创建分区表:
CREATE TABLE x PARTITION BY LIST (c_test) [range ()]
(PARTITION p0 VALUES [less than ](1) tablespace tbs1,
PARTITION p2 VALUES (2) tablespace tbs1,
PARTITION xsb1_p0 VALUES ([maxvalue]default))
AS SELECT * FROM xsb2 [where 1=2];

2.交换分区 alter table x exchange partition p0 with table bsvcbusrundatald ;

3.原表改名alter table bsvcbusrundatald rename to x0;

4.新表改名alter table x rename to bsvcbusrundatald ;

5.删除原表drop table x0;

6.创建新表触发器和索引create index ind_busrundata_lp on bsvcbusrundatald(。。。) local tablespace tbs_brd_ind ;

或者:

1.规划原大表中数据分区的界限,原则上将原表中近期少量数据复制至另一表;

2.暂停原大表中的相关触发器;

3.删除原大表中近期数据;

4.改名原大表名称;

5.创建分区表;

6.交换分区;

7.重建相关索引及触发器(先删除之再重建).

参考脚本:

select count(*) from t1 where recdate>sysdate-2

create table x2 nologging as select * from t1 where recdate>trunc(sysdate-2)

alter triger trg_t1 disable

delete t1 where recdate>sysdate-2

commit

rename t1 to x1

create table t1 [nologging] partition by range(recdate)

(partition pbefore values less than (trunc(sysdate-2)),

partition pmax values less than (maxvalue))

as select * from x1 where 1=2

alter table t1 exchange partition pbefore with table x1

alter table t1 exchange partition pmax with table x2

drop table x2

[重建触发器]

drop table x1

1.1.4参考材料:

如果表中预期的数据量较大通常都需要考虑使用分区表确定使用分区表后还要确定什么类型的分区range partitionhash partitionlist partition、分区区间大小等。分区的创建最好与程序有某种默契,偶曾经创建分区表,按自然月份定义分区的,但程序却在查询时默认的开始时间与结束时间是:当前日期-30至当前日期,比如当天是9.18号,那查询条件被产生为8.18-9.18,结果分区后并不没有大幅提高性能,后来对程序的查询日期做了调整,按自然月查询,系统的负载小了很多。

Oracle8.0开始支持表分区(MSSQL2005开始支持表分区)。

Oracle9i 分区能够提高许多应用程序的可管理性、性能与可用性。分区可以将表、索引及索引编排表进一步划分,从而可以更精细地对这些数据库对象进行管理和访问。Oracle 提供了种类繁多的分区方案以满足所有的业务需要。另外,由于在 SQL 语句中是完全透明的,所以分区可以用于几乎所有的应用程序。

分区表允许将数据分成被称为分区甚至子分区的更小的更好管理的块。索引也可以这么分区。每个分区可以被单独管理,可以不依赖于其他分区而单独发挥作用,因此提供了一个更有利于可用性和性能的结构。

分 区可以提高可管理性、性能与可用性,从而给各种各样的应用程序带来极大的好处。通常,分区可以使某些查询以及维护操作的性能大大提高。此外,分区还能够在 很大程度上简化日常管理任务。分区还使数据库设计人员和管理员能够解决尖端应用程序带来的最难的问题。分区是建立上亿万字节数据系统或需要极高可用性系统 的关键工具。

在多CPU配置环境下,如果打算使用并行执行,则分区提供了另一种并行的方法。通过给表或索引的不同分区分配不同的并行执行服务器,就可以并行执行对分区表和分区索引的操作。

表或索引的分区和子分区都共享相同的逻辑属性。例如表的所有分区或子分区共享相同的列和约束定义,一个索引的分区或子分区共享相同的索引选项。然而它们可以具有不同的物理属性如表空间。

尽管不需要将表或索引的每个分区或子分区放在不同的表空间,但这样做更好。将分区存储到不同的表空间能够

l减少数据在多个分区中冲突的可能性

l可以单独备份和恢复每个分区

l控制分区与磁盘驱动器之间的映射对平衡I/O 负载是重要的

l改善可管理性可用性和性能

分区操作对现存的应用和运行在分区表上的标准DML 语句来说是透明的。但是可以通过在DML 中使用分区扩展表或索引的名字来对应用编程,使其利用分区的优点。

可以使用SQL*LoaderImport Export 工具来装载或卸载分区表中的数据。这些工具都是支持分区和子分区的。

分区的方法

Oracle9i 提供了如下5种分区方法:

l范围分区Range

l散列分区Hash

l列表分区List

l组合范围-散列分区Range-Hash

l组合范围-列表分区Range-List

可对索引和表分区。全局索引只能按范围分区,但可以将其定义在任何类型的分区或非分区表上。通常全局索引比局部索引需要更多的维护。

一般组建局部索引,以便反映其基础表的结构。它与基础表是等同分区的,即它与基础

表在同样的列上分区,创建同样数量的分区或子分区,设置与基础表相对应的同样的分区边界。对局部索引而言,当维护活动影响分区时,会自动维护索引分区。这保证了索引与基础表之间的等同分区。

关于范围分区Range

要想将行映射到基于列值范围的分区,就使用范围分区方法。当数据可以被划分成逻辑范围时如年度中的月份,这种类型的分区就有用了。当数据在整个范围中能被均等地划分时性能最好。如果靠范围的分区会由于不均等的划分而导致分区在大小上明显不同时,就需要考虑其他的分区方法。

关于散列分区Hash

如果数据不那么容易进行范围分区,但为了性能和管理的原因又想分区时,就使用散列分区方法。散列分区提供了一种在指定数量的分区中均等地划分数据的方法。基于分区键的散列值将行映射到分区中。创建和使用散列分区会给你提供了一种很灵活的放置数据的方法,因为你可以通过在I/O 驱动器之间播撒(摘掉)这些均等定量的分区,来影响可用性和性能。

关于列表分区List

当 你需要明确地控制如何将行映射到分区时,就使用列表分区方法。可以在每个分区的描述中为该分区列指定一列离散值,这不同于范围分区,在那里一个范围与一个 分区相关,这也不同于散列分区,在那里用户不能控制如何将行映射到分区。列表分区方法是特意为遵从离散值的模块化数据划分而设计的。范围分区或散列分区不 那么容易做到这一点。进一步说列表分区可以非常自然地将无序的和不相关的数据集进行分组和组织到一起。

与范围分区和散列分区所不同,列表分区不支持多列分区。如果要将表按列分区,那么分区键就只能由表的一个单独的列组成,然而可以用范围分区或散列分区方法进行分区的所有的列,都可以用列表分区方法进行分区。

关于组合范围-散列分区:

范围和散列技术的组合,首先对表进行范围分区,然后用散列技术对每个范围分区再次分区。给定的范围分区的所有子分区加在一起表示数据的逻辑子集。

关于组合范围-列表分区:

范围和列表技术的组合,首先对表进行范围分区,然后用列表技术对每个范围分区再次分区。与组合范围-散列分区不同的是,每个子分区的所有内容表示数据的逻辑子集,由适当的范围和列表分区设置来描述。

创建或更改分区表时可以指定行移动子句,即ENABLE ROW MOVEMENT DISABLE ROW MOVEMENT ,当其键被更改时该子句启用或停用将行迁移到一个新的分区。默认值为DISABLE ROW MOVEMENT。本产品(项目)使用ENABLE ROW MOVEMENT子句。

分区技术能够提高数据库的可管理性:

使用分区技术,维护操作可集中于表的特定部分。例如,数据库管理员可以只对表的一部分做备份,而不必对整个表做备份。对整个数据库对象的维护操作,可以在每个分区的基础上进行,从而将维护工作分解成更容易管理的小块。

分区技术提高可管理性的一个典型用法是支持数据仓库中的滚动视窗加 载进程。假设数据库管理员每周向表中加载新数据。该表可以是范围分区,以便每个分区包含一周的数据。加载进程只是简单地添加新的分区。添加一个新分区的操 作比修改整个表效率高很多,因为数据库管理员不需要修改任何其他分区。从分区后的表中去除数据也是一样。你只要用一个很简便快捷的数据字典操作删掉一个分 区,而不必发出使用大量资源和调动所有要删除的数据的 ‘DELETE’ 命令。

分区技术能够提高数据库的性能:

由于减少了所检查或操作的数据数量,同时允许并行执行,Oracle9i 的分区功能提供了性能上的优势。这些性能包括:

l分 区修整:分区修整是用分区技术提高性能的最简单最有价值的手段。分区修整常常能够将查询性能提高几个数量级。例如,假定应用程序中有包含定单历史记录的定 单表,该表用周进行了分区。查询一周的定单只需访问该定单表的一个分区。如果该定单表包含两年的历史记录,这个查询只需要访问一个而不是一百零四个分区。 该查询的执行速度因为分区修整而有可能快一百倍。分区修整能与所有其他 Oracle 性能特性协作。Oracle 公司将把分区修整技术与索引技术、连结技术和并行访问方法一起联合使用。

l分 区智能联接:分区功能可以通过称为分区智能联接的技术提高多表联接的性能。当两个表要联接在一起,而且每个表都用联接关键字来分区时,就可以使用分区智能 联接。分区智能联接将大型联接分解成较小的发生在各个分区间的联接,从而用较少的时间完成全部联接。这就给串行和并行的执行都能带来显著的性能改善。

l更新和删除的并行执行:分区功能能够无限地并行执行 UPDATEDELETE MERGE 语句。当访问分区或未分区的数据库对象时Oracle 将并行处理 SELECT INSERT 语句。当不使用位图索引时,也可以对分区或未分区的数据库对象并行处理 UPDATEDELETE MERGE 语句。为了对有位图索引的对象并行处理那些操作,目标表必须先分区。这些 SQL 语句的并行执行可以大大提高性能,特别是提高 UPDATE DELETE MERGE 操作涉及大量数据时的性能。

分区技术提高可用性:

分 区的数据库对象具有分区独立性。该分区独立性特点可能是高可用性战略的一个重要部分,例如,如果分区表的分区不能用,但该表的所有其他分区仍然保持在线并 可用。那么这个应用程序可以继续针对该分区表执行查询和事务处理,只要不是访问那个不可用的分区,数据库操作仍然能够成功运行。 数据库管理员可以指定各分区存放在不同的表空间里,从而让管理员独立于其它表分区针对每个分区进行备份与恢复操作。 还有,分区功能可以减少计划停机时间。性能由于分区功能得到了改善,使数据库管理员在相对较小的批处理窗口完成大型数据库对象的维护工作。

posted @ 2009-11-15 10:10 gdufo 阅读(263) | 评论 (0)编辑 收藏

仅列出标题
共19页: First 上一页 8 9 10 11 12 13 14 15 16 下一页 Last 

导航

统计

常用链接

留言簿(6)

随笔分类

随笔档案

文章分类

文章档案

收藏夹

Hibernate

友情链接

搜索

最新评论

阅读排行榜

评论排行榜