索引高手看看吧
一张空表,表上有2个索引,
准备要插入300万条数据。
方案a,把表上的索引drop 掉,而后再插入300万条数据,插完后再建索引。
方案b,不对索引进行任何操作,直接插入300万条数据.
普遍的观点会建议用方案a.
我想问的是:
   1,方案b是一边插入一边维护索引吗?(如插入100万条时维护100万条数据的索引)。
   2,方案b是插入300万条数据完成后,再维护索引吗?如果是这样的话,和方案a的区别是什么?

解决方案 »

  1.   

    1,方案b是一边插入一边维护索引吗?(如插入100万条时维护100万条数据的索引)。 
    维护整个表的的索引
    2,方案b是插入300万条数据完成后,再维护索引吗?如果是这样的话,和方案a的区别是什么?
    边插入边维护,方案a不需要牺牲系能维护索引
      

  2.   


    答:方案b应该是一边插入数据一边维护索引。在此你可以假想一下(以主键为例:主键约等于(除去null)唯一索引),如果方案b是插入完后再维护索引的话,那么在提交数据前就可以插入相同的主键例了(在此没有用延迟check的约束),这与实际的情况不同----反证法。
      

  3.   

    a方法:全部插入后,再一次性维护,耗时较少
    b方法:每插入一条都要去维护一次索引,系统资源消耗比较多,浪费时间目标表为空表时,我觉得用a方法较好。
    目标表已有数据时,个人认为b方法较好
      

  4.   


    ---------------------
    1,方案A确实如楼主所述是边插入table记录边维护索引;
        我们考虑一下索引的维护方式,首先oracle会根据插入记录的索引值,找到该条索引应该存储在index中的位置,最佳条件下(比如唯一索引)也需要三个到四个(根据索引的degree不同会有区别)逻辑读,当然,如果是普通索引,由于相同值存在的原因,这个逻辑读次数可能会更多;好吧,我们就假设每条记录插入引起4个逻辑读吧,这样300万条记录插进去将会引起1200万次的逻辑读,假设你的缓存命中率为99%,这里也需要12万次逻辑读,另外还要加上若干次的逻辑write过程。
    2,方案B也正如楼主所述是在插入后统一执行对索引的维护过程;
        同样,我们模拟一下这个维护过程,oracle会首先将插入的内容按照索引值进行排序,也就是说,将索引值临近的结果一次性插入多条,我们这里假设一个索引block中可以插入100条本次插入的记录值,容纳全部的索引值需要3万个数据块,这时oracle将会遍历全部的index block,寻找合适的block插入index value,这样,需要执行的逻辑读次数将是索引的全部块数,肯定要比1200万少。