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

Oracle 向表中添加200列的性能影响

askTom 2016-08-04
299

问题描述

嗨,团队,

我对表上的列数有疑问。目前,我们在一个表中有66列,我们想在该表中添加额外的204列。我的问题是它会影响数据库性能并导致行链接与否?

DB块大小为16K。请确认其后果。

问候,
斯里达尔

专家解答

Oracle可以存储在行段中的最大列数为255。因此,您的270列将分为两行。

http://docs.oracle.com/database/121/CNCPT/logical.htm#CNCPT1055

这些可能在不同的块中,或者它们可能在同一块中。这取决于您要插入的值以及当时块中还剩下多少空间!

因此,如果您在表的 “末尾” 选择整行或整列,那么与255列或更少的表相比,将会有额外的工作。

您可以在下面的示例中看到这一点。我创建一个300列表,插入一行并添加索引。

仅选择表中的第一列会得到两个获取 (一个用于索引,一个用于行)。

但是选择整行或仅在末尾的列会得到三个获取 (一个用于索引,两个用于两个行)。

declare
  tab_sql varchar2(4000);
  ins_sql varchar2(4000);
begin
with rws as (
  select 'create table t ( ' 
  || listagg('col'||rownum || ' int', ',') within group (order by rownum) 
  || ')' tab,
  'insert into t values ( ' 
  || listagg('1', ',') within group (order by rownum) 
  || ')' ins
  from dual connect by level <= 300
)
  select *
  into   tab_sql, ins_sql
  from rws;
  
  execute immediate tab_sql;
  execute immediate ins_sql;
end;
/
create index i on t(col1);

SQL> set autotrace trace stat
SQL> select /*+ index(t(col1))*/col1, col2, col3
  2  from t
  3  where  col1 = 1;


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        486  bytes sent via SQL*Net to client
        500  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>
SQL> select /*+ index(t(col1))*/* from t
  2  where  col1 = 1;


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
      17929  bytes sent via SQL*Net to client
        500  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>
SQL> select /*+ index(t(col1))*/col300
  2  from t
  3  where  col1 = 1;


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        374  bytes sent via SQL*Net to client
        500  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

所以对于一些查询会有少量的额外工作。

您无法真正避免这种情况。说你而不是改变你现有的表,而是创建一个新的表。现在,您可以在每个行中少于255行。

但是!

如果您需要访问所有列,则现在需要将两个表连接起来。因此,您仍然可以从两个表中访问块。而且您可能也为新表提供了额外的索引查找。所以你救了自己一个问题,创造了另一个!

一如既往地在你的环境中进行测试。添加列,看看有什么影响。如果需要根据这些测试的结果考虑其他选择。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论