Sql 在使用函数索引的表上删除行后,如何清理未使用的空间?

Sql 在使用函数索引的表上删除行后,如何清理未使用的空间?,sql,database,oracle,tablespace,Sql,Database,Oracle,Tablespace,如何正确清理表空间 例如,我们有一个包含数百万行和函数索引的表。我们想移除桌子的大部分 为此,我们称之为:从某个表中删除,其中 接下来的步骤是什么 这个顺序正确吗? 1.删除函数索引。 2.改变一些表格缩小空间。 3.再次创建函数索引 创建新表 从旧表中选择*,其中 放下旧桌子 将newtable重命名为oldtable 重新创建索引 创建新表 从旧表中选择*,其中 放下旧桌子 将newtable重命名为oldtable 重新创建索引 正如您可能意识到的(或者您不会特别询问基于函数的索引),您不

如何正确清理表空间

例如,我们有一个包含数百万行和函数索引的表。我们想移除桌子的大部分

为此,我们称之为:从某个表中删除,其中

接下来的步骤是什么

这个顺序正确吗? 1.删除函数索引。 2.改变一些表格缩小空间。 3.再次创建函数索引

  • 创建新表 从旧表中选择*,其中
  • 放下旧桌子
  • 将newtable重命名为oldtable
  • 重新创建索引
  • 创建新表 从旧表中选择*,其中
  • 放下旧桌子
  • 将newtable重命名为oldtable
  • 重新创建索引
  • 正如您可能意识到的(或者您不会特别询问基于函数的索引),您不能简单地:

    alter table mytable enable row movement;
    alter table mytable shrink space;
    alter table mytable disable row movement;
    
    尝试这样做将导致:

    ORA-10631:不应为此对象指定SHRINK子句

    (注意:此限制也适用于位图连接索引。)

    很明显,你可以先放下FBI

    drop index my_fbi_index;
    alter table mytable enable row movement;
    alter table mytable shrink space;
    alter table mytable disable row movement;
    create index my_fbi_index... online;
    
    但这不是一个在线操作。您的应用程序将在短时间内受到缺少基于函数的索引的影响

    如果您需要联机操作,并且您使用的是Oracle 12.2或更高版本,您可以尝试以下操作:

    alter table mytable move online;
    
    alter table…move
    (无“联机”)在12.2之前可用,但它不是联机操作,它将删除索引段,留下标记为“不可用”的索引,并要求您重新生成。因此,在12.2之前,这不是一个好的选择。)

    正如您可能意识到的那样(或者您不会特别询问基于函数的索引),您不能简单地:

    alter table mytable enable row movement;
    alter table mytable shrink space;
    alter table mytable disable row movement;
    
    尝试这样做将导致:

    ORA-10631:不应为此对象指定SHRINK子句

    (注意:此限制也适用于位图连接索引。)

    很明显,你可以先放下FBI

    drop index my_fbi_index;
    alter table mytable enable row movement;
    alter table mytable shrink space;
    alter table mytable disable row movement;
    create index my_fbi_index... online;
    
    但这不是联机操作。您的应用程序将在短时间内受到缺少基于函数的索引的影响

    如果您需要联机操作,并且您使用的是Oracle 12.2或更高版本,您可以尝试以下操作:

    alter table mytable move online;
    
    alter table…move
    (无“联机”)在12.2之前可用,但它不是联机操作,它将删除索引段,使索引标记为“不可用”,并要求您重新生成。因此,在12.2之前,这并不是一个好的选择。)

    最佳方法 创建一个只包含有效数据的新表,并在其中重新创建索引,然后删除旧表

    • 使用过滤后的数据创建新表,其中table_name是表的名称,filter_text是以“where…”开头的条件,partitionText是一个分区子句(如果表中有),例如
      RANGE(ENDEDAT)INTERVAL(NUMTODSINTERVAL(1,“day”)(分区p_的第一个值小于(TO_DATE))(“01-01-2010”、“dd-MM-yyyy”)启用行移动
    • 向新表添加属性
    例如,约束、索引……这些可以从内置表中收集,例如所有约束、所有索引。属性的移动也可以自动化,只需要应用一些重命名技巧

    • 更改旧表和新表
    • 扔掉那张旧桌子
    立即执行“DROP TABLE”| | v| u TABLE| | | | OT”

    太长了,读不下去了,关于缩写和ReRog表 这里有一些关于我的调查的信息和有用的链接,当我考虑在直播DBs上归档大量数据时

    自动缩小某些表并处理其中的错误的方法 可收缩的桌子没有任何折衷 在收缩前/收缩后检查这些,进行测试 在我的例子中,我创建了一个包含数百万行的表(未分区),然后删除其中的1/3,结果如下:

                    ||     BYTES     ||  BLOCKS     ||
    Before deletion ||   105250816   ||  12848      ||
    After deletion  ||    78774272   ||   9616      ||
    
    调查和副作用 可能的副作用

    …何时应使用reorg:

    启用行移动,而收缩空间可以对行重新排序(这意味着如果使用基于ROWID的作业或选择或类似操作,则可能会有一些意外)

    最佳方式 创建一个只包含有效数据的新表,并在其中重新创建索引,然后删除旧表

    • 使用过滤后的数据创建新表,其中table_name是表的名称,filter_text是以“where…”开头的条件,partitionText是一个分区子句(如果表中有),例如
      RANGE(ENDEDAT)INTERVAL(NUMTODSINTERVAL(1,“day”)(分区p_的第一个值小于(TO_DATE))(“01-01-2010”、“dd-MM-yyyy”)启用行移动
    • 向新表添加属性
    例如,约束、索引……这些可以从内置表中收集,例如所有约束、所有索引。属性的移动也可以自动化,只需要应用一些重命名技巧

    • 更改旧表和新表
    • 扔掉那张旧桌子
    立即执行“DROP TABLE”| | v| u TABLE| | | | OT”

    太长了,读不下去了,关于缩写和ReRog表 这里有一些关于我的调查的信息和有用的链接,当我考虑在直播DBs上归档大量数据时

    自动缩小某些表并处理其中的错误的方法 可收缩的桌子没有任何折衷 在收缩前/收缩后检查这些,进行测试 在我的例子中,我创建了一个包含数百万行的表(未分区),然后删除其中的1/3,结果如下:

                    ||     BYTES     ||  BLOCKS     ||
    Before deletion ||   105250816   ||  12848      ||
    After deletion  ||    78774272   ||   9616      ||
    
    调查和副作用 可能的副作用

    …何时应使用reorg:

    启用行移动,而收缩空间可以对行重新排序(这意味着如果使用基于行ID的作业
    SELECT obj.owner
    ,obj.table_name
    ,(CASE WHEN NVL(idx.cnt, 0) < 1 THEN 'Y' ELSE 'N' END) as shrinkable
    FROM all_tables obj,
    (SELECT table_name, COUNT(rownum) cnt
    FROM user_indexes 
    WHERE index_type LIKE 'FUN%'
    GROUP BY table_name) idx
    WHERE obj.table_name = idx.table_name(+)
    AND NVL(idx.cnt,0) < 1
    --and obj.table_name like 'T_%' and obj.table_name not like 'TMP_%'
    and obj.compression != 'ENABLED'
    and obj.table_name not in (SELECT table_name FROM user_tab_partitions WHERE compression = 'ENABLED')
    and obj.owner='YOUR_SCHEMA_OWNER'
    
    SELECT table_name,compression, compress_for FROM   user_tables WHERE  compression = 'ENABLED'
    
    
    SELECT table_name,partition_name, compression, compress_for FROM   user_tab_partitions WHERE  compression = 'ENABLED' ORDER BY 1
    
    select segment_name,bytes/1024/1024 as mb,blocks from user_segments where segment_name='TABLE_NAME'
    
                    ||     BYTES     ||  BLOCKS     ||
    Before deletion ||   105250816   ||  12848      ||
    After deletion  ||    78774272   ||   9616      ||