Oracle表中含有255列以上是需要注意的(r12笔记第77天)


   今天看JL(Jonathan Lewis)的一篇文章,真是费了不少的脑细胞,玩Oracle几十年的老司机,看问题的角度和深度果然不一样,当时看他的大作《Oracle核心技术》就花了我不少时间,还没有看完,一本薄薄的书能够蕴含如此的能量,做技术到了这个火候,让人深深佩服。

   他的一篇博文,标题很简单,就是“255 again”看来是一个很经典的问题,我就简单抓取一些测试的思路和脚本来说说。

原文在链接 https://jonathanlewis.wordpress.com/2017/05/23/255-again/

   如果你的某张表列数超过255个,你就需要注意了,会有一些特别的问题出现,而对于这个问题的模拟,JL提供了一个脚本,会创建320个字段,然后对这个表插入一行数据,更新一行数据,然后根据block的dump来做一个分析和说明,脚本如下: rem
rem     Script: wide_table_4.sql
rem     Author: Jonathan Lewis
rem     Dated:  May 2017
rem
rem     Last tested
rem             12.2.0.1
rem             12.1.0.2
rem             11.2.0,4
rem
 
set pagesize 0
set feedback off
spool temp.sql
prompt create table t1(
 
select
        'col' || to_char(rownum,'fm0000') || '  varchar2(10),'
from
        all_objects
where   rownum <= 320
;
prompt col0321 varchar2(10)
prompt )
prompt /
spool off
 
@temp
 
set pagesize 40
set feedback on
 
insert into t1 (col0010, col0280) values ('0010','0280');
commit;
 
update t1 set col0320 ='0320';
commit;
 
column file_no  new_value m_file_no
column block_no new_value m_block_no
 
select
        dbms_rowid.rowid_relative_fno(rowid)    file_no,
        dbms_rowid.rowid_block_number(rowid)    block_no,
        dbms_rowid.rowid_row_number(rowid)      row_no
from
        t1
;
 
alter system flush buffer_cache;

脚本执行后,会创建一个含有320个字段的表,然后对标所在的dump做一个trace。

ntab=1
nrow=2
frre=-1
fsbo=0x16
fseo=0x1e54
avsp=0x1e3e
tosp=0x1f13
0xe:pti[0]      nrow=2  offs=0
0x12:pri[0]     offs=0x1e7a
0x14:pri[1]     offs=0x1e54
block_row_dump:
tab 0, row 0, @0x1e7a
tl: 49 fb: -------- lb: 0x2  cc: 40
nrid:  0x014000a7.0
col  0: *NULL*
col  1: *NULL*
col  2: *NULL*
...
col 37: *NULL*
col 38: *NULL*
col 39: *NULL*
tab 0, row 1, @0x1e54
tl: 38 fb: --H-F--- lb: 0x2  cc: 25
nrid:  0x014000a3.0
col  0: *NULL*
col  1: *NULL*
col  2: *NULL*
...
col 22: *NULL*
col 23: *NULL*
col 24: *NULL*
end_of_block_dump有几个点需要注意,这个块被分成了两部分,"row 1"所在的那部分这个块的起点(可以通过fb中的标记H,意思就是header),可以从末尾的cc看出涉及的列有25个,行的下一部分可以通过nrid来看,就是nrid:  0x014000a3.0转换过来就是5号数据文件,163号数据块,这个和row 1所在的数据库相同。

 如果我们看row 0的时候,会根据基本信息得到,它涉及的列数有40个,40个列都是空的,这一行指向的下行地址是nrid:  0x014000a7.0这个地址转换过来是在5号数据文件的167号块,根据这一行中间的标注(为空),感觉是一个可有可无的部分。我们就继续对5号数据文件的167号块做一个dump,得到的信息如下:

fsbo=0x14
fseo=0x1e76
avsp=0x1e62
tosp=0x1e62
0xe:pti[0]      nrow=1  offs=0
0x12:pri[0]     offs=0x1e76
block_row_dump:
tab 0, row 0, @0x1e76
tl: 266 fb: -----L-- lb: 0x1  cc: 255
col  0: *NULL*
col  1: *NULL*
col  2: *NULL*
...
col 251: *NULL*
col 252: *NULL*
col 253: *NULL*
col 254: [ 4]  30 33 32 30
end_of_block_dump   通过上面的信息可以发现,这是行数据的最后一部分,可以通过哪个L得到,(即last).

  所以一个初步结论如下:

  1. 一般的insert语句会把使用到的280个列分成两部分(25,255),这个280列可以通过Insert语句看到。

insert into t1 (col0010, col0280) values ('0010','0280');  2.在updae的场景中,我们把使用到的列从280升到了320

update t1 set col0320 ='0320';所以说在update的场景中,我们可以把列的使用情况从280改进到了320个列,这40个列在orale中会跟255为分界来处理,这样就是(40,295),然后把40列放在原来的数据块中,剩下的把255个列迁移到一个新的块中,所以这样一来,原来列的的分布就很有特点了,分配到了两个块中。后面还有对于ASSM在这个过程中的分析,限于篇幅和脑细胞数量,就暂时告一段落吧。

时间: 2024-08-30 01:42:59

Oracle表中含有255列以上是需要注意的(r12笔记第77天)的相关文章

oracle表 中删除一列

1.测试 在sys用户下创建测试表: SQL> create table t  as select object_id,object_name from dba_objects; 表已创建. SQL> select count(*)from t ;  COUNT(*) ---------- 48940 删除object_name 列: SQL> alter table t drop column object_name; alter table t drop column object_

如何写SQL实现:在数据表中增加一列,该列的值是出库数的累加 (按制单日期升序累加)

问题描述 如何写SQL实现:在数据表中增加一列,该列的值是出库数的累加 (按制单日期升序累加) 如上图,在数据表中增加一列[累计出库数],累计出库数的值等于出库数的累加数(按制单日期升序累加),如何写SQL实现 解决方案 Oracle有现成的lead,lag函数 其他数据库看下面我的博客 sqlserver http://blog.csdn.net/danielinbiti/article/details/45308867 mysqlhttp://blog.csdn.net/danielinbi

编程-VFP 更新表数据时自动把系统时间写入表中指定一列插入 如何实现自动写入数据

问题描述 VFP 更新表数据时自动把系统时间写入表中指定一列插入 如何实现自动写入数据 VFP编程 现有 成绩 用户 两表 成绩表 三列 成绩 修改时间 用户 用户表 两列 用户名 密码 其中插入与更新成绩后,自动提取系统时间 写入 "修改时间列"( 包含年月日的时间 ) 并且根据系统登录的用户,将用户名写入成绩表 用户列 修改时间以及 用户 这两列只能通过程序自动写入 不可以人为写入 现有两表 教师 用户 如何实现插入教师表中教师号一列的数据后 自动将数据插入到用户表中 用户名列 用

dorado7 在原有的表中添加一列 点提交怎么表存到数据库中

问题描述 dorado7 在原有的表中添加一列 点提交怎么表存到数据库中 dorado7 在原有的表中添加一列"酒店含早餐" 点提交怎么表存到数据库中(新加了一列") <Dataset method=""getDatasHotelAndMealByReqId"" type=""Wrapper"" id=""dsEvecHotelAndMeal"" ob

java-mysql表中改变一列数据的编号怎么让同编号的一行数据跟着变化?

问题描述 mysql表中改变一列数据的编号怎么让同编号的一行数据跟着变化? mysql表中改变一列数据的编号怎么让同编号的一行数据跟着变化?就是例如每个时间对应一行数据 我把时间列的顺序改变后 每个时间对应的数据还是不变 解决方案 用修改触发器实现

Python如何将一个列表写入到一个excel表中的一列,求Python代码,谢啦!

问题描述 Python如何将一个列表写入到一个excel表中的一列,求Python代码,谢啦! Python如何将一个列表写入到一个excel表中的一列,求Python代码,谢啦! 解决方案 有python的excel库,可以直接调用继续插入这里是这个库的链接https://pypi.python.org/pypi/xlrd 解决方案二: 找python读写excel的组件,即可搞定. 解决方案三: from pyExcelerator import * w = Workbook() #创建一个

数据库表中的一列值为:2007-06-12 列的存储类型为:datatime 但是在Asp.net网面上通过DataList绑定后显示的值为:2007-06-12 0:00:00?????????????????

问题描述 数据库表中的一列值为:2007-06-12列的存储类型为:datatime但是在Asp.net网面上通过DataList绑定后显示的值为:2007-06-120:00:00?怎么样通过DataList控件绑定后让他不显示:0:00:00,而只显示:1985-06-12 解决方案 解决方案二:sql语句不要直接选出时间字段t,拼字符串year(t)+month(t)+day(t)asnewtime解决方案三:'<%#Bind("DateTime","{0:yyy

oracle-为什么用plsql删除Oracle表中的字段,过一段时间怎么几个字段又出来了

问题描述 为什么用plsql删除Oracle表中的字段,过一段时间怎么几个字段又出来了 为什么删除Oracle数据库中某张表的字段,怎么过一会几个字段又出来了呢??? 用的hibernate和spring,, 这个是什么情况 解决方案 会不会是hibernate自动帮你建的啊?

SQL Server表中添加新列并添加描述_MsSql

注: sql server 2005 及以上支持. 版本估计是不支持(工作环境2005,2008). 工作需要, 需要向SQL Server 现有表中添加新列并添加描述. 从而有个如下存储过程. (先附上存储过程然后解释) /********调用方法********** 作用: 添加列并添加列描述信息 调用: exec [SetColumnInfo] '表名', '列名', N'列说明,描述','列类型{默认:NVARCHAR(50)}','列默认值{默认:NULL}' ************