表中有几千万条数据,我想把这张表分一下区
有两种方法:一,新建一个分好区的表,把这几千万条数据插入该新表。
            二,直接对这张有'几千万条数据'的表分一下区。
问题: 1,这两个方法哪个更好更快?
       2,如果第二个方法更好的话,请给一些关于‘有数据的表’的 分区代码
       3,分好区之后还要对索引分区吗?为什么?

解决方案 »

  1.   

    1.觉得方法一比较好。因为分区重导数据过程中,可以对数据进行一些处理,而万一导入过程中出了什么差错,也可以从断点的地方继续开始导数据,导之前不建索引不建pk,分批次commit还是很快的。而方法二要求联机重定义dbms_redefinition来做,万一出问题可能会造成锁表或其他问题。
    2.参考以下链接:
    http://hi.baidu.com/jinny/blog/item/0a65fbeda3a6b64d79f05506.html
    3.是否建分区索引要看需求的。如果建了分区索引,在分区索引字段上查询的时候会只用到这个区的索引数据,而如果不是的话,会进行全索引扫描,读的索引数据会是好几倍,当然也就慢了。
      

  2.   

    Oracle 分区表
    Oracle提供了分区技术以支持VLDB(Very Large DataBase)。分区表通过对分区列的判断,把分区列不同的记录,放到不同的分区中。分区完全对应用透明。 
    Oracle的分区表可以包括多个分区,每个分区都是一个独立的段(SEGMENT),可以存放到不同的表空间中。查询时可以通过查询表来访问各个分区中的数据,也可以通过在查询时直接指定分区的方法来进行查询。 Oracle的普通表没有办法通过修改属性的方式直接转化为分区表,必须通过重建的方式进行转变,下面介绍三种效率比较高的方法,并说明它们各自的特点。 方法一:利用原表重建分区表。 
    步骤: 
    SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE); 
    表已创建。 
    SQL> INSERT INTO T SELECT ROWNUM, CREATED FROM DBA_OBJECTS; 
    已创建6264行。 
    SQL> COMMIT; 
    提交完成。 
    SQL> CREATE TABLE T_NEW (ID, TIME) PARTITION BY RANGE (TIME) 
      2  (PARTITION P1 VALUES LESS THAN (TO_DATE('2004-7-1', 'YYYY-MM-DD')), 
      3  PARTITION P2 VALUES LESS THAN (TO_DATE('2005-1-1', 'YYYY-MM-DD')), 
      4  PARTITION P3 VALUES LESS THAN (TO_DATE('2005-7-1', 'YYYY-MM-DD')), 
      5  PARTITION P4 VALUES LESS THAN (MAXVALUE)) 
      6  AS SELECT ID, TIME FROM T; 
    表已创建。 
    SQL> RENAME T TO T_OLD; 
    表已重命名。 
    SQL> RENAME T_NEW TO T; 
    表已重命名。 
    SQL> SELECT COUNT(*) FROM T; 
      COUNT(*) 
    ---------- 
          6264 
    SQL> SELECT COUNT(*) FROM T PARTITION (P1); 
      COUNT(*) 
    ---------- 
            0 
    SQL> SELECT COUNT(*) FROM T PARTITION (P2); 
      COUNT(*) 
    ---------- 
          6246 
    SQL> SELECT COUNT(*) FROM T PARTITION (P3); 
      COUNT(*) 
    ---------- 
            18 
    优点:方法简单易用,由于采用DDL语句,不会产生UNDO,且只产生少量REDO,效率相对较高,而且建表完成后数据已经在分布到各个分区中了。 
    不足:对于数据的一致性方面还需要额外的考虑。由于几乎没有办法通过手工锁定T表的方式保证一致性,在执行CREATE TABLE语句和RENAME T_NEW TO T语句直接的修改可能会丢失,如果要保证一致性,需要在执行完语句后对数据进行检查,而这个代价是比较大的。另外在执行两个RENAME语句之间执行的对T的访问会失败。 
    适用于修改不频繁的表,在闲时进行操作,表的数据量不宜太大。 方法二:使用交换分区的方法
    ....对于local索引,每一个表分区对应一个索引分区,当表的分区发生变化时,索引的维护由Oracle自动进行。对于global索引,可以选择是否分区,而且索引的分区可以不与表分区相对应。当对分区进行维护操作时,通常会导致全局索引的INVALDED,必须在执行完操作后 REBUILD。分区索引是不能整体重建的,不能用
    SQL>alter index loc_xxxx_col rebuild;可以指定分区进行重建:SQL>alter index loc_xxxx_col rebuild partition 分区名 online; 
    使用online来尽可能减少创建过程中出现的任何加锁问题。如果你要整体新建,必须先drop 原有分区索引,然后
    SQL>create index loc_xxxx_col on xxxx(col) local tablespace SYSTEM;
    这是一个代价比较大的操作,要求有较大的临时表空间和排序区
    更多内容参看我的blog:
    http://blog.csdn.net/tianlesoftware/archive/2009/10/24/4717318.aspx
    对表分区,肯定是要搞个环境测试下的, 不可能直接在生产环境上了。 你测试下,那个速度块就用那个...
    ------------------------------------------------------------------------------
    Blog: http://blog.csdn.net/tianlesoftware
    网上资源: http://tianlesoftware.download.csdn.net
    相关视频:http://blog.csdn.net/tianlesoftware/archive/2009/11/27/4886500.aspx
    Q Q 群:62697716