仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 504|回复: 7
打印 上一主题 下一主题

[学习教程] MYSQL网页设计关于Oracle数据库中行迁徙/行链接的成绩...

[复制链接]
小女巫 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 22:42:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
不管怎么样,市场的结果已经证明MySQL具有性价比高、灵活、MySQL学习教程广为使用和具有良好支持的特点。oracle|链接|数据|数据库|成绩
1、行迁徙/行链接的先容

在实践的事情中我们常常会碰着一些Oracle数据库功能较低的成绩,固然,引发Oracle数据库功能较低的缘故原由是多方面的,我们可以经由过程一些准确的计划和诊断来只管的制止一些Oracle数据库功能欠好,RowMigration(行迁徙)&RowChaining(行链接)就是个中我们能够只管制止的引发Oracle数据库功能低下的潜伏成绩。经由过程公道的诊断行迁徙/行链接,我们能够较年夜幅度上进步Oracle数据库的功能。

那事实甚么是行迁徙/行链接呢,先让我们从Oracle的block入手下手谈起。

操纵体系的最小读写操纵单位是操纵体系的block,以是当创立一个Oracle数据库的时分我们应当讲数据库的blocksize设置成为操纵体系的blocksize的整数倍,Oracleblock是Oracle数据库中读写操纵的最小单位,Oracle9i之前的Oracle数据库版本中Oracleblock一旦在创立数据库的时分被设定后就没法再变动。为了在创立数据库之前断定一个公道的Oracleblock的巨细,我们必要思索一些要素,比方数据库自己的巨细和并发事件的数目等。利用一个符合的Oracleblock巨细关于数据库的调优长短常主要的。Oracleblock的布局以下图所示:







图一:OracleBlock布局图





由上图我们能够看出,一个Oracleblock由三个部分构成,分离是数据块头、自在空间、实践数据三部分构成。

数据块头:次要包括无数据块地点的一些基础信息和段的范例,和表和包括无数据的实践行的地点。

自在空间:是指能够为今后的更新和拔出操纵分派的空间,巨细由PCTFREE和PCTUSED两个参数影响。

实践数据:是指外行内存储的实践数据。

当创立大概变动任何表和索引的时分,Oracle在空间把持方面利用两个存储参数:

PCTFREE:为未来更新已存在的数据预留空间的百分比。

PCTUSED:用于为拔出一新行数据的最小空间的百分比。这个值决意了块的可用形态。可用的块时能够实行拔出的块,不成用形态的块只能实行删除和修正,可用形态的块被放在freelist中。

当表中一行的数据不克不及在一个数据block中放进的时分,这个时分就会产生两种情形,一种是行链接,别的一种就是行迁徙了。

行链接发生在第一次拔出数据的时分假如一个block不克不及寄存一行纪录的情形下。这类情形下,Oracle将利用链接一个大概多个在这个段中保存的block存储这一行纪录,行链接对照简单产生在对照年夜的行上,比方行上有LONG、LONGRAW、LOB等数据范例的字段,这类时分行链接是不成制止的会发生的。

当一行纪录初始拔出的时分事能够存储在一个block中的,因为更新操纵招致行长增添了,而block的自在空间已完整满了,这个时分就发生了行迁徙。在这类情形下,Oracle将会迁徙整行数据到一个新的block中(假定一个block中能够存储下整行数据),Oracle会保存被迁徙行的原始指针指向新的寄存行数据的block,这就意味着被迁徙行的ROWID是不会改动的。

当产生了行迁徙大概行链接,对这行数据操纵的功能就会下降,由于Oracle必需要扫描更多的block来取得这行的信息。

上面举例来详细申明行迁徙/行链接的发生历程。

先创立一个pctfree为20和pctused为50的测试表:

createtabletest(

col1char(20),

col2number)

storage(

pctfree20

pctused50);

当拔出一笔记录的时分,Oracle会在freelist中先往寻觅一个自在的块,而且将数据拔出到这个自在块中。而在freelist中存在的自在的块是由pctfree值决意的。初始的空块都是在freelist中的,直到块中的自在空间到达pctfree的值,此块就会从freelist中移走,而当此块中的利用空间低于pctused的时分,此块又被从头放到freelist中。

Oracle利用freelist机制能够年夜年夜的进步功能,关于每次的拔出操纵,Oracle只必要查找freelist就能够了,而不是往查找一切的block来寻觅自在空间。

假定第一次拔出数据利用的一个空的block,以下图所示:



图二:Oracle空的block布局图

假定拔出第一笔记录的时分占用一个block的10%的空间(撤除block头占往的巨细),残剩的自在空间90%年夜于pctfree20%,因而这个block还将持续为下次的拔出操纵供应空间。



图三:拔出10%后的Oracleblock布局图

再一连拔出七笔记录,使block的残剩自在空间剩下20%,此时,这个block将要从freelist中移走,假如再拔出纪录,Oracle将再freelist中寻觅下一个空余的block往寄存厥后拔出的数据。



图四:拔出80%后的Oracleblock布局图

此时假如往更新第一条拔出的纪录,使其行长增添15%,Oracle将会利用这个block中残剩的20%的自在空间来寄存此行数据,假如再更新第二笔记录,一样的使其行长增添15%,而此block中只剩下5%的自在空间,不敷寄存更新的第二笔记录,因而Oracle会在freelist中寻觅一个有自在空间(10%+15%)的block来寄存这行纪录的block往存储,在本来的block中保留了指向新的block的指针,本来这行纪录的ROWID坚持稳定,这个时分就发生了行迁徙。

而当我们拔出一条新记录的时分,假如一个blcok不敷以寄存下这笔记录,Oracle就会寻觅必定数目的block一同来包容这条新的纪录,这个时分就发生了行链接,行链接次要发生在LOB、CLOB、BLOB和年夜的VA行链接HAR2数据范例上。

详细我们经由过程上面的一个实验来检察行链接和行迁徙是怎样发生并在数据文件中表现出来的。






先检察ALLAN这个表空间的数据文件号,为了便于测试,我只创建了一个数据文件。

SQL>selectfile_idfromdba_data_fileswheretablespace_name=ALLAN;

FILE_ID

----------

23

创立一个测试表test:

SQL>createtabletest(xintprimarykey,achar(2000),bchar(2000),cchar(2000),dchar(2000),echar(2000))tablespaceallan;

Tablecreated.

由于我的数据库的db_block_size是8K,以是我创立的表有五个字段,每一个占2000个字节,如许一行纪录约莫10K,就可以凌驾一个block的巨细了。

然后拔出一行纪录,只要一个字段的:

SQL>insertintotest(x)values(1);

1rowcreated.

SQL>commit;

Commitcomplete.

查找这行纪录地点的block,并dump出来:

SQL>selectdbms_rowid.rowid_block_number(rowid)fromtest;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)

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

34

SQL>altersystemdumpdatafile23block34;

Systemaltered.

在udump目次下检察trace文件的内容以下:

Startdumpdatablockstsn:34file#:23minblk34maxblk34

buffertsn:34rdba:0x05c00022(23/34)

scn:0x0000.013943f3seq:0x01flg:0x02tail:0x43f30601

frmt:0x02chkval:0x0000type:0x06=transdata

Blockheaderdump:0x05c00022

ObjectidonBlock?Y

seg/obj:0x3ccdcsc:0x00.13943efitc:2flg:Otyp:1-DATA

fsl:0fnx:0x0ver:0x01

ItlXidUbaFlagLckScn/Fsc

0x010x000a.02e.00000ad70x00800036.03de.18--U-1fsc0x0000.013943f3

0x020x0000.000.000000000x00000000.0000.00----0fsc0x0000.00000000

data_block_dump,dataheaderat0xadb505c

===============

tsiz:0x1fa0

hsiz:0x14

pbl:0x0adb505c

bdba:0x05c00022

76543210

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

f搜索引擎优化=0x1f9a

avsp=0x1f83

tosp=0x1f83

0xe:pti[0]nrow=1offs=0

0x12:pri[0]offs=0x1f9a

block_row_dump:

tab0,row0,@0x1f9a

tl:6fb:--H-FL--lb:0x1cc:1

col0:[2]c102

end_of_block_dump

Enddumpdatablockstsn:34file#:23minblk34maxblk34

对个中的一些信息做一些注释:

Fb:H是指行纪录的头,L是指行纪录的最初一列,F是指行纪录的第一列。

Cc:列的数目

Nrid:关于行链接大概行迁徙来讲的下一个rowid的值

由下面的dump信息我们能够看出来以后表test是没有行链接大概行迁徙的。

然后更新test表,偏重新dump出来:

SQL>updatetestseta=test,b=test,c=test,d=test,e=testwherex=1;

1rowupdated.

SQL>commit;

Commitcomplete.

此时应当有行迁徙/行链接发生了。

SQL>altersystemdumpdatafile23block34;

Systemaltered.

在udump目次下检察trace文件的内容以下:

Startdumpdatablockstsn:34file#:23minblk34maxblk34

buffertsn:34rdba:0x05c00022(23/34)

scn:0x0000.0139442bseq:0x01flg:0x02tail:0x442b0601

frmt:0x02chkval:0x0000type:0x06=transdata

Blockheaderdump:0x05c00022

ObjectidonBlock?Y

seg/obj:0x3ccdcsc:0x00.1394429itc:2flg:-typ:1-DATA

fsl:0fnx:0x0ver:0x01

ItlXidUbaFlagLckScn/Fsc

0x010x000a.02e.00000ad70x00800036.03de.18C---0scn0x0000.013943f3

0x020x0004.002.00000ae00x0080003b.0441.11--U-1fsc0x0000.0139442b

data_block_dump,dataheaderat0xadb505c

===============

tsiz:0x1fa0

hsiz:0x14

pbl:0x0adb505c

bdba:0x05c00022

76543210

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

f搜索引擎优化=0x178a

avsp=0x177c

tosp=0x177c

0xe:pti[0]nrow=1offs=0

0x12:pri[0]offs=0x178a

block_row_dump:

tab0,row0,@0x178a

tl:2064fb:--H-F--Nlb:0x2cc:3

nrid:0x05c00023.0

col0:[2]c102

col1:[2000]

74657374202020202020202020202020202020202020202020

20202020202020202020202020202020202020202020202020

…………

col2:[48]

74657374202020202020202020202020202020202020202020

2020202020202020202020202020202020202020202020

end_of_block_dump

Enddumpdatablockstsn:34file#:23minblk34maxblk34

我们不丢脸出,nrid呈现了值,指向了下一个rowid,证实方才的update操纵使这行纪录发生了行链接大概行迁徙了。




2、行迁徙/行链接的检测

经由过程后面的先容我们晓得,行链接次要是因为数据库的db_block_size不敷年夜,关于一些年夜的字段没法在一个block中存储下,从而发生了行链接。关于行链接我们除增年夜db_block_size以外没有其余任何举措往制止,可是由于数据库创建后db_block_size是不成改动的(在9i之前),关于Oracle9i的数据库我们能够对分歧的表空间指定分歧的db_block_size,因而行链接的发生几近是不成制止的,也没有太多能够调剂的中央。行迁徙则次要是因为更新表的时分,因为表的pctfree参数设置太小,招致block中没有充足的空间往包容更新后的纪录,从而发生了行迁徙。关于行迁徙来讲就十分有调剂的需要了,由于这个是能够调剂和把持扫除的。

怎样检测数据库中存在有了行迁徙和行链接呢?我们能够使用Oracle数据库本身供应的剧本utlchain.sql(在$ORACLE_HOME/rdbms/admin目次下)天生chained_rows表,然后使用ANALYZETABLEtable_nameLISTCHAINEDROWSINTOchained_rows命令逐一剖析表,将剖析的了局存进chained_rows表中。从utlchain.sql剧本中我们看到chained_rows的建表剧本,关于分区表,cluster表都是合用的。然后可使用拼集语句的举措天生剖析所必要的表的剧本,并实行剧本将详细的剖析数据放进Chained_rows表中,比方上面是剖析一个用户下一切表的剧本:


SPOOLlist_migation_rows.sql

SETECHOOFF

SETHEADINGOFF

SELECTANALYZETABLE||table_name||LISTCHAINEDROWSINTOchained_rows;FROMuser_tables;

SPOOLOFF


然后查询chained_rows表,能够详细检察某张表上有几的行链接和行迁徙。


SELECTtable_name,count(*)fromchained_rowsGROUPBYtable_name;


固然,也能够查询v$sysstat视图中的’tablefetchcontinuedrow’列失掉以后的行链接和行迁徙数目。


SELECTname,valueFROMv$sysstatWHEREname=tablefetchcontinuedrow;


可使用以下的剧本来间接查找存在有行链接和行迁徙的表,主动完成一切的剖析和统计。


acceptownerprompt"EntertheschemanametocheckforRowChaining(RETURNforAll):"
prompt
prompt
accepttableprompt"Enterthetablenametocheck(RETURNforAlltablesownedby&owner):"
prompt
prompt
setheadoffserveroutontermonfeedoffverioffechooff
!clear
prompt
declare
v_ownervarchar2(30);
v_tablevarchar2(30);
v_chainsnumber;
v_rowsnumber;
v_countnumber:=0;
sql_stmtvarchar2(100);
dynamicCursorINTEGER;
dummyINTEGER;
cursorchainsis
selectcount(*)fromchained_rows;
cursoranalyzeis
selectowner,table_name
fromsys.dba_tables
whereownerlikeupper(%&owner%)
andtable_namelikeupper(%&table%)
orderbytable_name;
begin
dbms_output.enable(64000);
openanalyze;
fetchanalyzeintov_owner,v_table;
whileanalyze%FOUNDloop
dynamicCursor:=dbms_sql.open_cursor;
sql_stmt:=analyzetable||v_owner||.||v_table||listchainedrowsintochained_rows;
dbms_sql.parse(dynamicCursor,sql_stmt,dbms_sql.native);
dummy:=dbms_sql.execute(dynamicCursor);
dbms_sql.close_cursor(dynamicCursor);
openchains;
fetchchainsintov_chains;
if(v_chains!=0)then
if(v_count=0)then
dbms_output.put_line(CHR(9)||CHR(9)||CHR(9)||<<<<<ChainedRowsFound>>>>>);
v_count:=1;
endif;
dynamicCursor:=dbms_sql.open_cursor;
sql_stmt:=Selectcount(*)v_rows||From||v_owner||.||v_table;
dbms_sql.parse(dynamicCursor,sql_stmt,dbms_sql.native);
dbms_sql.DEFINE_COLUMN(dynamicCursor,1,v_rows);
dummy:=dbms_sql.execute(dynamicCursor);
dummy:=dbms_sql.fetch_rows(dynamicCursor);
dbms_sql.COLUMN_VALUE(dynamicCursor,1,v_rows);
dbms_sql.close_cursor(dynamicCursor);
dbms_output.put_line(v_owner||.||v_table);
dbms_output.put_line(CHR(9)||--->Has||v_chains||ChainedRowsand||v_rows||Num_Rowsinit!);
dynamicCursor:=dbms_sql.open_cursor;
sql_stmt:=truncatetablechained_rows;
dbms_sql.parse(dynamicCursor,sql_stmt,dbms_sql.native);
dummy:=dbms_sql.execute(dynamicCursor);
dbms_sql.close_cursor(dynamicCursor);
v_chains:=0;
endif;
closechains;
fetchanalyzeintov_owner,v_table;
endloop;
if(v_count=0)then
dbms_output.put_line(NoChainedRowsfoundinthe||v_owner||ownedTables!);
endif;
closeanalyze;
end;
/
setfeedonheadon
prompt




3、行迁徙和行链接的扫除

因为关于行链接来讲只能增年夜db_block_size来扫除,而db_block_size在创立了数据库后又是不克不及改动了的,以是这里对行链接的扫除不做过量的叙说了,次要是针对行迁徙来谈谈在实践的临盆体系中怎样往扫除。

关于行迁徙的扫除,一样平常来讲分为两个步骤:第一步,把持住行迁徙的增加,使其不在增加;第二步,扫除失落之前存在的行迁徙。

尽人皆知,行迁徙发生的次要缘故原由是由于表上的pctfree参数设置太小招致的,而要完成第一步把持住行迁徙的增加,就必需设置好一个准确符合的pctfree参数,不然即便扫除了以后的行迁徙后即刻又会发生良多新的行迁徙。固然,这个参数也不是越年夜越好的,假如pctfree设置的过年夜,会招致数据块的使用率低,形成空间的大批华侈,因而必需设置一个公道的pctfree参数。怎样往断定一个表上公道的pctfree参数呢,一样平常来讲有两种办法。

第一种是定量的的设定办法,就是使用公式来设定pctfree的巨细。先利用ANALYZETABLEtable_nameESTIMATESTATISTICS命令来剖析要修正pctfree的表,然后检察user_tables中的AVG_ROW_LEN列值,失掉一个均匀行长AVG_ROW_LEN1,然后大批的对表操纵以后,再次利用上述命令剖析表,失掉第二个均匀行长AVG_ROW_LEN2,然后使用公式100*(AVG_ROW_LEN2-AVG_ROW_LEN1)/(AVG_ROW_LEN2-AVG_ROW_LEN1+原始的AVG_ROW_LEN)得出的了局就是定量盘算出来的一个符合的pctfree的值。这类办法由于是定量盘算出来的,大概纷歧定会很正确,并且由于要剖析表,以是关于利用RBO实行企图的体系不是很合用。比方:avg_row_len_1=60,avg_row_len_2=70,则均匀修正量为10,PCTFREE应调剂为100*10/(10+60)=16.7%。

第二种是差分微调的办法,先查询到以后表的pctfree的值,然后监控和调剂pctfree参数,每次增添一点pctfree的巨细,每次增添的比例不要凌驾5个百分点,然后利用ANALYZETABLETABLE_NAMELISTCHAINEDROWSINTOchained_rows命令剖析每次一切的行迁徙和行链接的增加情形,关于分歧的表接纳分歧的增加比例,关于行迁徙增加的对照快的表pctfree值就增添的多点,关于增加慢的表就增添的少点,直到表的行迁徙基础坚持不增加了为止。可是注重不要把pctfree调的过年夜,一样平常在40%以下就能够了,不然会形成空间的很年夜华侈和增添数据库会见的IO。

利用上述的办法把持住了以后表的行迁徙的增加以后,就能够入手下手扫除之前表上存在的行迁徙了。是不是扫除失落行迁徙,干系到体系的功能是不是可以有很年夜的进步。因而,关于之前存在的行迁徙是必定并且必需要扫除失落的。扫除失落已存在的行迁徙有良多办法,可是并非一切的办法都能合用一切的情形,比方表中的纪录数几,表上的联系关系几、表下行迁徙的数目几等等这些要素城市是成为制约你利用甚么办法扫除的前提,因而,依据表的特性和详细情形的分歧我们应当接纳分歧的办法往扫除行迁徙。上面我将一一先容各类扫除行迁徙的办法和它们各自合用的分歧情形。

办法一:传统的扫除行迁徙的办法

详细步骤以下:

1.实行$ORACLE_HOME/rdbms/admin目次下的utlchain.sql剧本创立chained_rows表。


@$ORACLE_HOME/rdbms/admin/utlchain.sql


2.将存在有行迁徙的表(用table_name取代)中的发生行迁徙的行的rowid放进到chained_rows表中。


ANALYZETABLEtable_nameLISTCHAINEDROWSINTOchained_rows;


3.将表中的行迁徙的rowid放进一时表中保留。


CREATETABLEtable_name_tempAS

SELECT*FROMtable_name

WHERErowidIN

(SELECThead_rowidFROMchained_rows

WHEREtable_name=table_name);


4.删除本来表中存在的行迁徙的纪录行。


DELETEtable_name

WHERErowidIN

(SELECThead_rowid

FROMchained_rows

WHEREtable_name=table_name);


5.从一时表中掏出偏重新拔出那些被删除的数据到本来的表中,并删除一时表。


INSERTINTOtable_nameSELECT*FROMtable_name_temp;

DROPTABLEtable_name_temp;


关于这类传统的扫除RM的办法,长处是实行起来历程对照复杂,简单完成。可是这类算法的缺点是没有思索到表联系关系的情形,在年夜多半数据库中良多表都是和其余表之间有表联系关系的,有外键的限定,如许就形成在步骤3中基本没法delete失落存在有行迁徙的纪录行,以是这类办法可以合用的表的局限是无限的,只能合用于表上无任何外键联系关系的表。因为这类办法在拔出和删除数据的时分都没有disable失落索引,如许招致次要损耗工夫是在删除和拔出时保持索引树的平衡上了,这个关于假如纪录数未几的情形工夫上还对照短,可是假如关于纪录数良多的表这个所损耗的工夫就不是可以承受的了。明显,这类办法在处置年夜数据量的表的时分明显是不成取的。

以下是一个详细在临盆数据库上扫除行迁徙的例子,在这之前已调剂过表的pctfree参数至一个符合的值了:


SQL>@$ORACLE_HOME/rdbms/admin/utlchain.sql

Tablecreated.

SQL>ANALYZETABLECUSTOMERLISTCHAINEDROWSINTOchained_rows;

Tableanalyzed.

SQL>SELECTcount(*)fromchained_rows;

TABLE_NAMECOUNT(*)

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

CUSTOMER21306

1rowsselected.

检察在CUSTOMER表上存在的限定:

SQL>selectCONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAMEfromUSER_CONSTRAINTSwhereTABLE_NAME=CUSTOMER;

CONSTRAINT_NAMECTABLE_NAME

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

PK_CUSTOMER1PCUSTOMER

SQL>selectCONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAMEfromUSER_CONSTRAINTSwhereR_CONSTRAINT_NAME=PK_CUSTOMER1;

norowsselected

SQL>CREATETABLECUSTOMER_tempAS

SELECT*FROMCUSTOMERWHERErowidIN

(SELECThead_rowidFROMchained_rows

WHEREtable_name=CUSTOMER);

Tablecreated.

SQL>selectcount(*)fromCUSTOMER;

COUNT(*)

----------

338299

SQL>DELETECUSTOMERWHERErowidIN

(SELECThead_rowid

FROMchained_rows

WHEREtable_name=CUSTOMER);

21306rowsdeleted.

SQL>INSERTINTOCUSTOMERSELECT*FROMCUSTOMER_temp;

21306rowscreated.

SQL>DROPTABLECUSTOMER_temp;

Tabledropped.

SQL>commit;

Commitcomplete.

SQL>selectcount(*)fromCUSTOMER;

COUNT(*)

----------

338299

SQL>truncatetablechained_rows;

Tabletruncated.

SQL>ANALYZETABLECUSTOMERLISTCHAINEDROWSINTOchained_rows;

Tableanalyzed.

SQL>selectcount(*)fromchained_rows;

COUNT(*)

----------

0


以上全部扫除两万多行的行迁徙历程在三分钟摆布,并且全体都在联机的形态下完成,基础上不会对营业有甚么影响,独一就是在要扫除行迁徙的表上不克不及有对外键的限定,不然就不克不及接纳这个办法往扫除了。



办法二:改善了的传统扫除行迁徙的办法

1.实行$ORACLE_HOME/rdbms/admin目次下的utlchain.sql剧本创立chained_rows表。

2.禁用一切别的表上联系关系到此表上的一切限定。

3.将表中的行迁徙的rowid放进一时表中保留。

4.删除本来表中存在的行迁徙的纪录行。

5.从一时表中掏出偏重新拔出那些被删除的数据到本来的表中,并删除一时表。

6.启用一切别的表上联系关系到此表上的一切限定。

这类算法是对传统算法的一种改善,关于利用这类算法来扫除行迁徙,思索到了表之间的联系关系,还能够天真的使用的TOAD工具天生的表联系关系信息,是一种对照合适于扫除行迁徙的一种办法。可是由于利用这类办法厥后必要重修索引,假如纪录数很年夜,好比说上万万条以上的纪录的表,就不是很符合了,由于这个重修索引的工夫会很长,是线性工夫庞大度的,而重修索引是会招致索引地点的表被锁定的,从而招致拔出不了新的纪录,重修索引的工夫太长招致纪录长工夫拔出不了是会严峻影呼应用的,乃至招致数据的丧失,因而这个是利用这个办法前必需要思索到的一个主要要素;关于8i以上的版本可使用online的办法来重修索引,如许不会招致锁表,可是会有分外更多的开支,工夫会很长。再者,由于这类办法在拔出纪录和删除纪录都是带着索引的,假如表上的行迁徙对照多,如许耗工夫会对照长,并且占用资本也会对照年夜,因而只合用于表下行迁徙存在的对照少的表。总的来讲,这类办法关于表纪录太多大概是表上的行迁徙太多的情形都不是很合用,对照合适表纪录少和表下行迁徙都不太多的情形。

以下是一个详细在临盆数据库上扫除行迁徙的例子,在这之前已调剂过表的pctfree参数至一个符合的值了:


SQL>selectindex_name,index_type,table_namefromuser_indexeswheretable_name=TERMINAL;

INDEX_NAMEINDEX_TYPETABLE_NAME

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

INDEX_TERMINAL_TERMINALCODENORMALTERMINAL

I_TERMINAL_ID_TYPENORMALTERMINAL

I_TERMINAL_OT_OIDNORMALTERMINAL

PK_TERMINAL_IDNORMALTERMINAL

UI_TERMINAL_GOODIS_SSNNORMALTERMINAL

SQL>selectCONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAMEfromUSER_CONSTRAINTSwhereR_CONSTRAINT_NAME=PK_TERMINAL_ID;

CONSTRAINT_NAMECTABLE_NAME

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

SYS_C003200RCONN

SQL>altertableCONNdisableconstraintSYS_C003200;

Tablealtered.

SQL>CREATETABLETERMINAL_tempAS

SELECT*FROMTERMINAL

WHERErowidIN

(SELECThead_rowidFROMchained_rows

WHEREtable_name=TERMINAL);

Tablecreated.

SQL>selectcount(*)fromTERMINAL_temp;

COUNT(*)

----------

8302

SQL>DELETETERMINAL

WHERErowidIN

(SELECThead_rowid

FROMchained_rows

WHEREtable_name=TERMINAL);

8302rowsdeleted.

SQL>INSERTINTOTERMINALSELECT*FROMTERMINAL_temp;

8302rowscreated.

SQL>altertableCONNdisableconstraintSYS_C003200;

Tablealtered.

SQL>selectcount(*)fromterminal;

COUNT(*)

----------

647799

SQL>truncatetablechained_rows;

Tabletruncated.

SQL>ANALYZETABLETERMINALLISTCHAINEDROWSINTOchained_rows;

Tableanalyzed.

SQL>selectcount(*)fromchained_rows;

COUNT(*)

----------

0


从下面过程当中能够看出,对TERMINAL这张表的行迁徙扫除耗时统共不到五分钟的工夫,整体来讲仍是对照快的。从我在临盆数据库中扫除行迁徙的履历来讲,这类办法基础合用于年夜部分存在有行迁徙的表。



办法三:利用TOAD工具扫除行迁徙的办法

1.备份要扫除RM的表。


RENAMEtable_nameTOtable_name_temp;


2.Drop一切别的表上联系关系到table_name的外键限定。


SELECTCONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAMEfromUSER_CONSTRAINTSwhereR_CONSTRAINT_NAMEin(SELECTCONSTRAINT_NAMEfromUSER_CONSTRAINTSwhereTABLE_NAME=table_nameANDCONSTRAINT_TYPE=’P’);

ALTERTABLEtable_nameDROPCONSTRAINTXXXX;(XXXX为上述的查询了局)


3.重修1中被rename的表。


CREATETABLEtable_nameASSELECT*FROMtable_name_tempWHERE0=1;


4.重修表华夏来的数据。


INSERT/*+APPEND*/INTOtable_nameSELECT*FROMtable_name_temp;


5.删除在table_name_temp上的索引和联系关系其他表的外键。

6.在table_name上创建和本来一样的索引、主键和一切的外键限定。

7.从头编译相干的存储历程、函数和包。

8.删除表table_name_temp。

关于利用这类办法来扫除行迁徙,全体的代码都是能够由TOAD工具来天生的。因为此办法把表上的联系关系思索出来了,也是一种对照的周全的思索的一种扫除办法,并且在扫除过程当中重修了表和索引,关于数据库的存储和功能上都有进步。由于这类办法一入手下手是rename表为一时表,然后重修一个新表出来的,因而必要两倍的表的空间,因而在操纵之前必定要反省要扫除的表地点的表空间的free空间是不是充足;可是也有必定的缺点,由于在新表中从头拔出本来的数据后必要重修索引和限定,因而在工夫和磁盘的空间上都有对照年夜的开支,并且关于前台的使用大概会有一段工夫的中止,固然,这其中断工夫就次要是损耗在重修索引和重修限定上了,而工夫的是非跟必要重修索引和限定的几和表的纪录几等等要素都有干系。利用这类办法关于7*24小时请求的体系上扫除行迁徙不是很符合,由于利用这类办法会招致体系大概有一段工夫的停机,假如体系的及时性对照高,这类办法就不是很合用了。



办法四:利用EXP/IMP工具扫除行迁徙的办法

1.利用EXP导出存在有行迁徙的表。

2.然后TRUNCATE本来的表。

3.IMP入手下手导出的表。

4.重修表上一切的索引。(可选)

利用这类办法能够不必重修索引,省往了这部分工夫,可是完成以后索引的利用效力不会很高,最好是在今后慢慢的在线重修索引,如许是能够不必要中止营业的。可是必要思索的是IMP的时分会对照慢,并且会占用对照年夜的IO,应当选择在使用不是很忙碌的时分做这项事情,不然会对使用的一般运转发生较年夜的影响。关于这类办法还存在有一个对照年夜的坏处,就是在EXP表的时分要包管该表是没无数据的更新大概是只读形态的,不克不及对表有拔出大概更新操纵,不然会招致数据的丧失。


SQL>selectcount(*)fromtest;

COUNT(*)

----------

169344

SQL>truncatetablechained_rows;

Tabletruncated.

SQL>analyzetabletestLISTCHAINEDROWSINTOchained_rows;

Tableanalyzed.

SQL>selectcount(*)fromchained_rows;

COUNT(*)

----------

3294

$expallan/allanfile=test.dmptables=test

Export:Release9.2.0.3.0-ProductiononSunJun613:50:082004

Copyright(c)1982,2002,OracleCorporation.Allrightsreserved.

Connectedto:Oracle9iEnterpriseEditionRelease9.2.0.3.0-Production

WiththePartitioning,OLAPandOracleDataMiningoptions

JServerRelease9.2.0.3.0-Production

ExportdoneinZHS16GBKcharactersetandAL16UTF16NCHARcharacterset

AbouttoexportspecifiedtablesviaConventionalPath...

..exportingtableTEST169344rowsexported

Exportterminatedsuccessfullywithoutwarnings.

$sqlplusallan/allan

SQL*Plus:Release9.2.0.3.0-ProductiononSunJun613:50:432004

Copyright(c)1982,2002,OracleCorporation.Allrightsreserved

Connectedto:

Oracle9iEnterpriseEditionRelease9.2.0.3.0-Production

WiththePartitioning,OLAPandOracleDataMiningoptions

JServerRelease9.2.0.3.0-Production

SQL>truncatetabletest;

Tabletruncated.

SQL>exit

DisconnectedfromOracle9iEnterpriseEditionRelease9.2.0.3.0-Production

WiththePartitioning,OLAPandOracleDataMiningoptions

JServerRelease9.2.0.3.0-Production

$impallan/allanfile=test.dmpfull=yignore=ybuffer=5000000

Import:Release9.2.0.3.0-ProductiononSunJun613:51:242004

Copyright(c)1982,2002,OracleCorporation.Allrightsreserved.

Connectedto:Oracle9iEnterpriseEditionRelease9.2.0.3.0-Production

WiththePartitioning,OLAPandOracleDataMiningoptions

JServerRelease9.2.0.3.0-Production

ExportfilecreatedbyEXPORT:V09.02.00viaconventionalpath

importdoneinZHS16GBKcharactersetandAL16UTF16NCHARcharacterset

.importingALLANsobjectsintoALLAN

..importingtable"TEST"169344rowsimported

Importterminatedsuccessfullywithoutwarnings.

$sqlplusallan/allan

SQL*Plus:Release9.2.0.3.0-ProductiononSunJun613:52:532004

Copyright(c)1982,2002,OracleCorporation.Allrightsreserved.

Connectedto:

Oracle9iEnterpriseEditionRelease9.2.0.3.0-Production

WiththePartitioning,OLAPandOracleDataMiningoptions

JServerRelease9.2.0.3.0-Production

SQL>selectcount(*)fromtest;

COUNT(*)

----------

169344

SQL>selectindex_namefromuser_indexeswheretable_name=TEST;

INDEX_NAME

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

OBJ_INDEX

SQL>alterindexOBJ_INDEXrebuildonline;

Indexaltered.

SQL>truncatetablechained_rows;

Tabletruncated.

SQL>analyzetabletestLISTCHAINEDROWSINTOchained_rows;

Tableanalyzed.

SQL>selectcount(*)fromchained_rows;

COUNT(*)

----------

0




办法五:利用MOVE命令来扫除行迁徙的办法

1.检察要扫除行迁徙的表地点的表空间。


Selecttable_name,tablespace_namefromuser_tableswheretable_name=table_name’;


2.检察要扫除行迁徙的表上的详细索引。


selectindex_name,table_namefromuser_indexeswheretable_name=‘table_name’;


3.Move要扫除RM的表到指定的表空间中往。


altertabletable_namemovetablespacetablespace_name;


4.重修表上的一切索引。


alterindexindex_namerebuild;


这类办法合用于8i及其以上的数据库版本,次要是使用数据库的一个MOVE命令来完成行迁徙的扫除的,MOVE命令的本色实在就是INSERT…SELECT的一个历程,在MOVE表的过程当中是必要两倍的本来的表巨细的,由于两头历程是要保存本来的旧表的,新表创立完成后旧表就被删除并开释空间了。MOVE的时分要注重前面必定要加上表空间参数,以是必需要先晓得表地点的表空间;由于MOVE表以后必要重修索引,以是之前要断定表上的一切的索引。

这类办法关于表纪录数很年夜大概表上索引太多的情形不太合用,由于自己的MOVE就会很慢,并且MOVE表的时分会要锁定表,工夫长了会招致对表的其他操纵呈现成绩,招致数据拔出不了丧失数据;MOVE表后还要重修索引,索引太多了的话重修的工夫也会太长;再者,这个办法也对照损耗资本,因而激烈倡议在营业不忙碌的时分再实行。

以下是一个详细在临盆数据库上扫除行迁徙的例子,在这之前已调剂过表的pctfree参数至一个符合的值了:


SQL>ANALYZETABLESERVICELISTCHAINEDROWSINTOchained_rows;

Tableanalyzed.

SQL>SELECTcount(*)fromchained_rows;

COUNT(*)

----------

9145

SQL>selecttable_name,tablespace_namefromuser_tableswheretable_name=SERVICE;

TABLE_NAMETABLESPACE_NAME

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

SERVICEDATA

SQL>selectindex_name,table_namefromuser_indexeswheretable_name=SERVICE;

INDEX_NAMETABLE_NAME

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

I_SERVICE_ACCOUNTNUMSERVICE

I_SERVICE_DATEACTIVATEDSERVICE

I_SERVICE_SC_SSERVICE

I_SERVICE_SERVICECODESERVICE

PK_SERVICE_SIDSERVICE

SQL>selectcount(*)fromSERVICE;

COUNT(*)

----------

518718

SQL>altertableSERVICEmovetablespaceDATA;

Tablealtered.

SQL>alterindexI_SERVICE_ACCOUNTNUMrebuild;

Indexaltered.

SQL>alterindexI_SERVICE_DATEACTIVATEDrebuild;

Indexaltered.

SQL>alterindexI_SERVICE_SC_Srebuild;

Indexaltered.

SQL>alterindexI_SERVICE_SERVICECODErebuild;

Indexaltered.

SQL>alterindexPK_SERVICE_SIDrebuild;

Indexaltered.

SQL>truncatetablechained_rows;

Tabletruncated.

SQL>ANALYZETABLESERVICELISTCHAINEDROWSINTOchained_rows;

Tableanalyzed.

SQL>SELECTcount(*)fromchained_rows;

COUNT(*)

----------

0


使用MOVE命令来扫除行迁徙,实行的命令都绝对对照的复杂,下面的例子中扫除表SERVCIE中的行迁徙的工夫也许在五分钟摆布,个中move命令实行的工夫为不到两分钟,也就是锁表的工夫也许是不到两分钟,关于年夜多半的使用来讲一样平常成绩都是不年夜的,放在体系闲的时分实行基础上不会对使用发生甚么太多的影响。



办法六:关于一些行迁徙数目伟大并且表纪录数伟大的表的行迁徙的扫除办法

1.利用TOAD工具大概其余办法猎取存在有大批行迁徙而且表纪录很年夜的表的重修表的SQL,然后保留为剧本。

2.利用RENAME命令将原始表重定名为一个备份表,然后删除其余表对原始表上的限定、和原始表上的外键和索引。

3.使用1中天生的剧本重修原始表,和表上的限定,外键,索引等工具。

4.然后按表形式导出2中备份的表,然后导进到别的的一个一时直达的数据库库中,由于表的名字已改动,以是导进后必要RENAME表为本来的名字,然后从头导出,最初再导进到本来的数据库中。

这类办法次要是用来针对一些数据量对照年夜,而且表上的行迁徙也对照多的表的行迁徙扫除。关于这些年夜表的行迁徙的扫除,一般来讲都必要停使用一段较长工夫才干够扫除失落,让人感到对照的头疼,关于7*24小时的使用来讲,down机的工夫越长丧失则越年夜,固然是要只管的减短down机的工夫。可是由于表自己对照年夜,不论如何做甚么操纵都是会对照泯灭工夫和资本的,可是假如使用在某段工夫内次要是以拔出数据为主,更新数据和删除数据都很少的,因而能够思索能够接纳这么一种办法:先重定名表,然后从头创建一个和本来一样的表,用来包管以后的使用的数据是能够一般拔出的,从而使使用不必停好久,由于重修一个没有任何数据的表布局的历程是很长久的,也许必要几秒钟的工夫,而重修好表了后就可以包管使用可以一般的写进数据,从而使使用几近不必停留,然后把入手下手重定名的原始表按表形式导出,由于表的名字已被改动,因而必要一个一时库来导进这些数据,然后重定名回本来的名字,然后按本来的表名导出后再从头导进原始数据库,如许操纵起来固然会对照贫苦,可是倒是一种很无效很实践的办法,速率也很快,导出后导进,由于自己表布局已创建好了,不必要其他任何的多的操纵,并且最关头的是这类办法所必要的down机工夫是最短的。


SQL>ALTERTABLEUSER.PAYRENAMETOPAY_X;

然后导出PAY_X表;

$expUSER/USERfile=PAY_X.dmptables=PAY_X

SQL>ALTERTABLEUSER.BATCHPAYMENTDETAILDROPCONSTRAINTFK_BATCHPAYMENTDETAIL_OPAYID;

SQL>ALTERTABLEUSER.DEPOSITCLASSIFYDROPCONSTRAINTFK_DEPOSITCLASSIFY2;

SQL>ALTERTABLEUSER.DEPOSITCREDITLOGDROPCONSTRAINTFK_DEPOSITCREDITLOG2;

SQL>ALTERTABLEUSER.DEPOSITDROPCONSTRAINTSYS_C003423;

SQL>ALTERTABLEUSER.PAY_XDROPCONSTRAINTSYS_C003549;

SQL>DROPINDEXUSER.I_PAY_STAFFID;

SQL>CREATETABLEUSER.PAY

(

PAYIDNUMBER(9),

ACCOUNTNUMNUMBER(9),

TOTALNUMBER(12,2),

PREVPAYNUMBER(12,2),

PAYNUMBER(12,2),

STAFFIDNUMBER(9),

PROCESSDATEDATE,

PAYNOCHAR(12),

TYPECHAR(2)DEFAULT0,

PAYMENTMETHODCHAR(1)DEFAULT0,

PAYMENTMETHODIDVARCHAR2(20),

BANKACCOUNTVARCHAR2(32),

PAYMENTIDNUMBER(9),

STATUSCHAR(1)DEFAULT0,

MEMOVARCHAR2(255),

SERVICEIDNUMBER(9),

CURRENTDEPOSITIDNUMBER(9),

SHOULDPROCESSDATEDATEDEFAULTsysdate,

ORIGINALEXPIREDATEDATE,

ORIGINALCANCELDATEDATE,

EXPIREDATEDATE,

CANCELDATEDATE,

DEPOSITTYPECHAR(1)

)

TABLESPACEUSER

PCTUSED95

PCTFREE5

INITRANS1

MAXTRANS255

STORAGE(

INITIAL7312K

NEXT80K

MINEXTENTS1

MAXEXTENTS2147483645

PCTINCREASE0

FREELISTS1

FREELISTGROUPS1

BUFFER_POOLDEFAULT

)

NOLOGGING

NOCACHE

NOPARALLEL;

SQL>CREATEINDEXUSER.I_PAY_STAFFIDONUSER.PAY

(STAFFID)

NOLOGGING

TABLESPACEUSER

PCTFREE5

INITRANS2

MAXTRANS255

STORAGE(

INITIAL1936K

NEXT80K

MINEXTENTS1

MAXEXTENTS2147483645

PCTINCREASE0

FREELISTS1

FREELISTGROUPS1

BUFFER_POOLDEFAULT

)

NOPARALLEL;

SQL>CREATEUNIQUEINDEXUSER.PK_PAY_IDONUSER.PAY

(PAYID)

NOLOGGING

TABLESPACEUSER

PCTFREE5

INITRANS2

MAXTRANS255

STORAGE(

INITIAL1120K

NEXT80K

MINEXTENTS1

MAXEXTENTS2147483645

PCTINCREASE0

FREELISTS1

FREELISTGROUPS1

BUFFER_POOLDEFAULT

)

NOPARALLEL;

SQL>ALTERTABLEUSER.PAYADD(

FOREIGNKEY(STAFFID)

REFERENCESUSER.STAFF(STAFFID));

SQL>ALTERTABLEUSER.DEPOSITCLASSIFYADD

CONSTRAINTFK_DEPOSITCLASSIFY2

FOREIGNKEY(PAYID)

REFERENCESUSER.PAY(PAYID);

SQL>ALTERTABLEUSER.DEPOSITCREDITLOGADD

CONSTRAINTFK_DEPOSITCREDITLOG2

FOREIGNKEY(PAYID)

REFERENCESUSER.PAY(PAYID);

SQL>ALTERFUNCTION"USER"."GENERATEPAYNO"COMPILE;

SQL>ALTERPROCEDURE"USER"."ENGENDERPRVPAY"COMPILE;

SQL>ALTERPROCEDURE"USER"."ISAP_ENGENDERPRVPAY"COMPILE;

SQL>ALTERPROCEDURE"USER"."SPADDCREDITDEPOSIT"COMPILE;

SQL>ALTERPROCEDURE"USER"."SPADDDEPOSITWITHOUTCARD"COMPILE;

SQL>ALTERPROCEDURE"USER"."SPADJUSTLWDEPOSIT"COMPILE;

……

然后将导出的表PAY_X的dmp文件导进一个一时的数据库中,然后在一时数据库中将其表名从头定名为PAY,再按表形式将其导出。

impUSER/USERfile=PAY_x.dmptables=PAYignore=y

SQL>renamePAY_XtoPAY;

$expUSER/USERfile=PAY.dmptables=PAY

最初将这个dmp文件导进正式的临盆数据库中便可。


以上的历程在重修好PAY表后全部使用就恢复一般了,而重定名表后重修表的工夫长短常之短的,我测试的工夫也许是在几分钟以内就能够做完了,新数据就能够拔出表了,剩下的事情就是将旧的数据导进数据库,这个事情的工夫请求上就没有那末高了,由于使用已一般了,一样平常来讲使用早晨营业不忙的时分都能够把一张表的数据导进完成的。

以上的六种扫除行迁徙的办法各有各自的优弱点,分离合用于分歧的情形下利用,使用以上的几种扫除行迁徙的办法基础上就可以完整扫除失落体系中的存在的行迁徙了,固然,详细的临盆情况中还必要详细成绩详细剖析的,针对分歧范例的体系,体系中分歧特性的表接纳分歧的扫除办法,只管的削减停数据库的工夫,以包管使用的不中断不乱运转。





图一:OracleBlock布局图





由上图我们能够看出,一个Oracleblock由三个部分构成,分离是数据块头、自在空间、实践数据三部分构成。

数据块头:次要包括无数据块地点的一些基础信息和段的范例,和表和包括无数据的实践行的地点。

自在空间:是指能够为今后的更新和拔出操纵分派的空间,巨细由PCTFREE和PCTUSED两个参数影响。

实践数据:是指外行内存储的实践数据。

当创立大概变动任何表和索引的时分,Oracle在空间把持方面利用两个存储参数:

PCTFREE:为未来更新已存在的数据预留空间的百分比。

PCTUSED:用于为拔出一新行数据的最小空间的百分比。这个值决意了块的可用形态。可用的块时能够实行拔出的块,不成用形态的块只能实行删除和修正,可用形态的块被放在freelist中。

当表中一行的数据不克不及在一个数据block中放进的时分,这个时分就会产生两种情形,一种是行链接,别的一种就是行迁徙了。

行链接发生在第一次拔出数据的时分假如一个block不克不及寄存一行纪录的情形下。这类情形下,Oracle将利用链接一个大概多个在这个段中保存的block存储这一行纪录,行链接对照简单产生在对照年夜的行上,比方行上有LONG、LONGRAW、LOB等数据范例的字段,这类时分行链接是不成制止的会发生的。

当一行纪录初始拔出的时分事能够存储在一个block中的,因为更新操纵招致行长增添了,而block的自在空间已完整满了,这个时分就发生了行迁徙。在这类情形下,Oracle将会迁徙整行数据到一个新的block中(假定一个block中能够存储下整行数据),Oracle会保存被迁徙行的原始指针指向新的寄存行数据的block,这就意味着被迁徙行的ROWID是不会改动的。

当产生了行迁徙大概行链接,对这行数据操纵的功能就会下降,由于Oracle必需要扫描更多的block来取得这行的信息。

上面举例来详细申明行迁徙/行链接的发生历程。

先创立一个pctfree为20和pctused为50的测试表:

createtabletest(

col1char(20),

col2number)

storage(

pctfree20

pctused50);

当拔出一笔记录的时分,Oracle会在freelist中先往寻觅一个自在的块,而且将数据拔出到这个自在块中。而在freelist中存在的自在的块是由pctfree值决意的。初始的空块都是在freelist中的,直到块中的自在空间到达pctfree的值,此块就会从freelist中移走,而当此块中的利用空间低于pctused的时分,此块又被从头放到freelist中。

Oracle利用freelist机制能够年夜年夜的进步功能,关于每次的拔出操纵,Oracle只必要查找freelist就能够了,而不是往查找一切的block来寻觅自在空间。

假定第一次拔出数据利用的一个空的block,以下图所示:



图二:Oracle空的block布局图

假定拔出第一笔记录的时分占用一个block的10%的空间(撤除block头占往的巨细),残剩的自在空间90%年夜于pctfree20%,因而这个block还将持续为下次的拔出操纵供应空间。



图三:拔出10%后的Oracleblock布局图

再一连拔出七笔记录,使block的残剩自在空间剩下20%,此时,这个block将要从freelist中移走,假如再拔出纪录,Oracle将再freelist中寻觅下一个空余的block往寄存厥后拔出的数据。



图四:拔出80%后的Oracleblock布局图

此时假如往更新第一条拔出的纪录,使其行长增添15%,Oracle将会利用这个block中残剩的20%的自在空间来寄存此行数据,假如再更新第二笔记录,一样的使其行长增添15%,而此block中只剩下5%的自在空间,不敷寄存更新的第二笔记录,因而Oracle会在freelist中寻觅一个有自在空间(10%+15%)的block来寄存这行纪录的block往存储,在本来的block中保留了指向新的block的指针,本来这行纪录的ROWID坚持稳定,这个时分就发生了行迁徙。

而当我们拔出一条新记录的时分,假如一个blcok不敷以寄存下这笔记录,Oracle就会寻觅必定数目的block一同来包容这条新的纪录,这个时分就发生了行链接,行链接次要发生在LOB、CLOB、BLOB和年夜的VA行链接HAR2数据范例上。

详细我们经由过程上面的一个实验来检察行链接和行迁徙是怎样发生并在数据文件中表现出来的。






先检察ALLAN这个表空间的数据文件号,为了便于测试,我只创建了一个数据文件。

SQL>selectfile_idfromdba_data_fileswheretablespace_name=ALLAN;

FILE_ID

----------

23

创立一个测试表test:

SQL>createtabletest(xintprimarykey,achar(2000),bchar(2000),cchar(2000),dchar(2000),echar(2000))tablespaceallan;

Tablecreated.

由于我的数据库的db_block_size是8K,以是我创立的表有五个字段,每一个占2000个字节,如许一行纪录约莫10K,就可以凌驾一个block的巨细了。

然后拔出一行纪录,只要一个字段的:

SQL>insertintotest(x)values(1);

1rowcreated.

SQL>commit;

Commitcomplete.

查找这行纪录地点的block,并dump出来:

SQL>selectdbms_rowid.rowid_block_number(rowid)fromtest;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)

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

34

SQL>altersystemdumpdatafile23block34;

Systemaltered.

在udump目次下检察trace文件的内容以下:

Startdumpdatablockstsn:34file#:23minblk34maxblk34

buffertsn:34rdba:0x05c00022(23/34)

scn:0x0000.013943f3seq:0x01flg:0x02tail:0x43f30601

frmt:0x02chkval:0x0000type:0x06=transdata

Blockheaderdump:0x05c00022

ObjectidonBlock?Y

seg/obj:0x3ccdcsc:0x00.13943efitc:2flg:Otyp:1-DATA

fsl:0fnx:0x0ver:0x01

ItlXidUbaFlagLckScn/Fsc

0x010x000a.02e.00000ad70x00800036.03de.18--U-1fsc0x0000.013943f3

0x020x0000.000.000000000x00000000.0000.00----0fsc0x0000.00000000

data_block_dump,dataheaderat0xadb505c

===============

tsiz:0x1fa0

hsiz:0x14

pbl:0x0adb505c

bdba:0x05c00022

76543210

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

f搜索引擎优化=0x1f9a

avsp=0x1f83

tosp=0x1f83

0xe:pti[0]nrow=1offs=0

0x12:pri[0]offs=0x1f9a

block_row_dump:

tab0,row0,@0x1f9a

tl:6fb:--H-FL--lb:0x1cc:1

col0:[2]c102

end_of_block_dump

Enddumpdatablockstsn:34file#:23minblk34maxblk34

对个中的一些信息做一些注释:

Fb:H是指行纪录的头,L是指行纪录的最初一列,F是指行纪录的第一列。

Cc:列的数应用程序需要使用数据库,数据库本身需要设计、开发和部署。还有MySQL学习教程,客户怎样实施混合系统,或者需要帮助管理多个云服务?
沙发
发表于 2015-1-19 21:20:48 | 只看该作者
同样会为索引视图等应用带来麻烦。看看行级和事务级的快照数据放在tempdb中,就能感觉到目前架构的尴尬。
admin 该用户已被删除
板凳
发表于 2015-1-25 20:58:49 | 只看该作者
一直以来个人感觉SQLServer的优化器要比Oracle的聪明。SQL2005的更是比2k聪明了不少。(有次作试验发现有的语句在200万级时还比50万级的相同语句要快show_text的一些提示没有找到解释。一直在奇怪。)
山那边是海 该用户已被删除
地板
发表于 2015-2-3 23:48:43 | 只看该作者
无法深入到数据库系统层面去了解和探究
再现理想 该用户已被删除
5#
发表于 2015-2-9 07:36:09 | 只看该作者
所以你总能得到相应的升级版本,来满足你的需求。
第二个灵魂 该用户已被删除
6#
发表于 2015-2-27 04:31:08 | 只看该作者
以前的DTS轻盈简单。但是现在的SSIS虽然功能强大了很多,但是总是让人感觉太麻烦。看看论坛中询问SSIS的贴子就知道。做的功能太强大了,往往会有很多用户不会用了
飘灵儿 该用户已被删除
7#
发表于 2015-3-16 13:29:55 | 只看该作者
很多书籍啊,不过个人认为看书太慢,还不如自己学。多做实际的东西,就会遇到很多问题,网上搜下解决问题。不断重复这个过程,在配合sql的F1功能。
愤怒的大鸟 该用户已被删除
8#
发表于 2015-3-22 23:10:18 | 只看该作者
而SQLServer如果能像Oracle一样可以为登陆分配如:5%的cpu,10%的内存。就可以解决这个漏洞。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-11-15 03:44

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表