精华内容
下载资源
问答
  • 很多用户经常会有将数据写入ArcSDE地理数据库的操作,也时常会写入效率而烦恼,它们渴望不管多大多复杂的数据,尽可能的使用较少的时间写入到ArcSDE中,而往往用户写入ArcSDE也通过依赖于本身的业务需求,使用自定义...

    很多用户经常会有将数据写入ArcSDE地理数据库的操作,也时常会写入效率而烦恼,它们渴望不管多大多复杂的数据,尽可能的使用较少的时间写入到ArcSDE中,而往往用户写入ArcSDE也通过依赖于本身的业务需求,使用自定义的代码开发就非常常见了,那影响ArcSDE写入效率的因素就比较多了。

    ----------------------------------------------------------------------------------

    版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

    Blog:               http://blog.csdn.net/linghe301

    ----------------------------------------------------------------------------------

    代码因素

    大多数用户可能还在使用ArcGIS Engine、空间SQL、ArcSDE API和WebAPI进行开发,针对后两者我不是很熟悉,也没有什么发言权,所以更多的以前面两种开发模式为例,看看在代码开发过程中是否有可以优化的余地。


                                                           ArcGIS Engine                                                    

    以下部分可以参考2011年Esri中国开发者大会《Geodatabase高效编程_李圣虎》,特此感谢!

    该文档建议ArcGIS Engine的开发者仔细学习,里面介绍了很多提高效率的技巧和细节!

    http://wenku.baidu.com/link?url=mgCFXh23Q3fbRaBjOJr-LN1b24_pbH_UylNcTt1zZ_hNROqByNzj8nRpV4IZrKulMYod9jxiOOeN8WGRgx0Y0Z_vLvEAZsjw2KSz2Uj0w0K


    另外大家也可以参考:Geodatabase API best practices 

    http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/index.html#//000100000047000000


    1:使用多线程

    说实话,ArcGIS Engine是否支持多线程,大家的理解是不一样的。用资深人士解释就是ArcGIS Engine支持多线程,但是不支持多个线程之间的彼此调用。

    下面就以更新多个要素类的字段来演示一下多线程的使用方法,以下都是伪代码。

    编写一个更新要素类的函数,输入参数为要素类名称

     public class VersionEditing
        {
            /// <summary>
            /// 更新要素类指定字段值
            /// </summary>
            /// <param name="parameter">要素类名称</param>
            public void UpdateFiledValue(object parameter)
            {
    		........
            }
          }
    编写多线程函数,调用这个更新要素类的函数
    private void MultiThreadEditing()
            {
                VersionEditing VersionEditing = new GIS.VersionEditing();
                //声明线程对象
                Thread thA = new Thread(new ParameterizedThreadStart(VersionEditing.UpdateFiledValue));
                Thread thB = new Thread(new ParameterizedThreadStart(VersionEditing.UpdateFiledValue));
                //设置线程工作模型
                thA.SetApartmentState(ApartmentState.STA);
                thB.SetApartmentState(ApartmentState.STA);
                //启动线程
                thA.Start("featureclass1");
                thA.Start("featureclass2");
            }

    2:使用游标进行地理数据库编辑

    如果是批量进行数据编辑,不建议用户使用传统的Create Feature+Store的方法,而是使用insertCursor或者Update Cursor的方法。

    //建议的方法
    public static void InsertFeaturesUsingCursor(IFeatureClass featureClass, List <
        IGeometry > geometryList)
    {
        using(ComReleaser comReleaser = new ComReleaser())
        {
            // Create a feature buffer.
            IFeatureBuffer featureBuffer = featureClass.CreateFeatureBuffer();
            comReleaser.ManageLifetime(featureBuffer);
    
            // Create an insert cursor.
            IFeatureCursor insertCursor = featureClass.Insert(true);
            comReleaser.ManageLifetime(insertCursor);
    
            // All of the features to be created are classified as Primary Highways.
            int typeFieldIndex = featureClass.FindField("TYPE");
            featureBuffer.set_Value(typeFieldIndex, "Primary Highway");
            foreach (IGeometry geometry in geometryList)
            {
                // Set the feature buffer's shape and insert it.
                featureBuffer.Shape = geometry;
                insertCursor.InsertFeature(featureBuffer);
            }
    
            // Flush the buffer to the geodatabase.
            insertCursor.Flush();
        }
    }

          测试场景:从本地File Geodatabase中读取数据,向ArcSDE Geodatabase要素类中插入读取的数据;
          数据情况:简单的线要素类,2721089条记录;
          测试环境:硬件(T9600 CPU 4G内存)软件(Windows 7 64Bit Oracle 11g ArcGIS 10)
          备注:测试结果中时间单位为秒



    3:游标

    游标分为类绑定游标: SearchCursor、UpdateCursor、InsertCursor和非类绑定游标:QueryDef Cursor。在使用游标使用过程中经常会遇到如下情况

    Public Void test()
    {                
    		workspaceEdit.StartEditOperation();
                    IQueryFilter queryFilter = new QueryFilter();
                    queryFilter.WhereClause = clause;
                    //是否重复绑定游标
                    ICursor updateCursor = table.Update(queryFilter, true);
                    comReleaser.ManageLifetime(updateCursor);
                    int fieldIndex = table.Fields.FindField("FWMC");
                    IRow temp = null;
                    while ((temp = updateCursor.NextRow()) != null)
                    {
                        temp.set_Value(fieldIndex, "aaaa");
                        updateCursor.UpdateRow(temp);
                    }
                    workspaceEdit.StopEditOperation();
    }

    如果选择TRUE,说明使用资源回收游标,但是下一个游标还指向同一个内存地址,如果是FALSE,说明资源回收游标和内存地址,下一个游标还需要重新分配一个新的内存地址,这样无疑增加了服务器资源的开销,所以没有特殊需求,建议使用TRUE。


    关于游标的相关提示:

    查询游标(Search Cursor)

    • 在编辑会话中初始化SearchCursor可能导致缓存记录提交到数据库(触发DBMS写操作)
    • 通过SearchCursor获得的行支持Store和Delete操作
    更新游标(Update Cursor)
    • 必须使用UpdateCursor提供的的UpdateRow和DeleteRow方法对通过UpdateCursor获得的行进行更新和删除操作
    • UpdateCursor提供的UpdateRow方法只能针对通过UpdateCursor获得的当前行进行操作
    • UpdateCursor不支持跨编辑操作使用,打开一个新的编辑操作时必须初始化一个新的更新游标
    • 使用UpdateCursor对复杂要类类进行更新时必须处于一个编辑会话中
    插入游标(Insert Cursor)
    • 主要用于批量要素插入
    • 使用缓存,定时调用Flush将缓存写入数据库,调用InsertRow和Flush方法时要捕捉异常
    • 使用InsertCursor时关闭空间缓存
    QueryDef 游标
    • 不能针对通过QueryDef Cursor获得的行进行Store和Delete操作
    • 在编辑会话中使用QueryDef Cursor会导致缓存提交到数据库
    4:资源回收
    尽可能使用Esri提供的MangeLifetime来管理ArcGIS Engine对象的生命周期,系统会自动进行维护,而不需要在使用类似以下方式进行释放资源了。(由于版本原因,可能有所不同)
     ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(o);
    
    System.Runtime.InteropServices.Marshal.ReleaseComObject(o);
    GC.Collect();


    5:如果可能化,使用缓存来提高效率

    /// <summary>
            /// 执行空间缓存
            /// </summary>
            /// <param name="pFWS">工作空间</param>
            /// <param name="pEnv">缓存区域</param>
            private void SpatialCache(IFeatureWorkspace pFWS, IEnvelope pEnv)
            {
                if (m_pWS != null)
                {
                    ISpatialCacheManager3 pSCM = m_pWS as ISpatialCacheManager3;
                    if (!pSCM.CacheIsFull)
                    {
                        pSCM.FillCache(pEnv);
                    }
    
                    //执行空间操作代码
    
                    //清空缓存
    
                    pSCM.EmptyCache();
                  
                }
            }

    更多了解:http://resources.arcgis.com/en/help/arcobjects-net/componenthelp/index.html#//002500000831000000


    6:如果可能的话,尽可能的使用GP工具来代替开发

    ArcGIS Desktop的性能无疑是最优化的,而且最大的好处就是实现了用户可以使用的ArcToolbox工具,而且ArcGIS Engine也可以进行调用,比如将一个File Geodatabase导入到ArcSDE 地理数据库中,用户就可以直接使用Copy_Feature工具进行操作。


    7:是否必须使用版本化编辑

    ArcGIS不仅支持版本编辑,也支持非版本编辑,所以并不是所有情况必须使用版本化编辑,大家都知道注册版本后编辑一段时间会导致效率低下,但是有些用户在一开始接触ArcGIS编辑时只知道必须注册版本才能编辑,但是它的业务情况可能并不需要必须注册版本,比如只是编辑一下属性字段值等情况,所以这个时候可能选择非版本编辑效率更高。

    IDatasetEdit


    更多参考:http://resources.arcgis.com/en/help/arcobjects-net/componenthelp/index.html#/IDatasetEdit_Interface/00250000015m000000/


    用户也可以查看《Geodatabase高效编程_李圣虎》总结的常见开发错误,都是一些比较典型的可能导致效率的案例。



                                                  空间SQL                                          

    对空间SQL的开发其实就是用户的SQL语句的基本功是否扎实。

    1:SQL语句语法和效率

    在SQL中,索引是提高查询效率的必要条件,尤其是WHERE子句的查询字段必须要创建索引才能提高查询效率,如果没有WHERE条件在查询中使用了MIN、MAX、COUNT函数的字段也需要创建索引。还有很多情况用户尽管创建了索引对象但效率依然低下,这是因为有些SQL运算符是会将索引失效的。


    •  使用不等于运算符(<>、!=)

    在WHERE中使用不等于条件,将会使索引失效。


    • 使用 IS NULL或IS NOT NULL

    在WHERE子句中使用IS NULL或者IS NOT NULL同样会限制索引的使用。如果被索引的列在某些行中存在NULL值,在索引列中就不会有相应的条目。(例外:位图索引对于NULL列也会进行记录,因此位图索引对于NULL搜索通常较为快速)。


    • 使用函数

    如果不使用基于函数的索引,那么在SQL语句的WHERE子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。一些常见的函数:TRUNC、SUBSTR、TO_DATE、TO_CHAR、INSTR等,都可能会使索引失效。


    •  比较不匹配的数据类型

    这个是比较难于发现的问题。ORACLE不会对不匹配的数据类型报错,ORACLE会隐式地把VARCHAR2列的数据类型转换成要被比较的数值型数据类型。


    如果是使用ST_geometry函数的话,还需要注意对ST_Geometry函数的使用

    具体可以参考:

    http://blog.csdn.net/linghe301/article/category/797871


    2:尽可能的使用存储过程

    如果可能的话,尽可能的使用存储过程来代替原始的单个SQL语句,这里面就不再解释存储过程的好处了。


    3:使用绑定变量而不是传入固定的值



    ----------------------------------------------------------------------------------

    版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

    Blog:               http://blog.csdn.net/linghe301

    ----------------------------------------------------------------------------------

                                                    网络因素                                                                                             

    网络的原因也是用户需要注意的,如果你的网络带宽、延迟都有问题,肯定会影响数据传输的效率的。这里我只是指出这是一个影响因素,因为不专业,所以不去更多的分析这个问题,但是用户需要留意该问题。

    ----------------------------------------------------------------------------------

    版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

    Blog:               http://blog.csdn.net/linghe301

    ----------------------------------------------------------------------------------


                      ArcSDE地理数据库因素(以Oracle为例)                                                 


    1:空间索引问题

    在ArcSDE地理数据库编辑过程中,系统会自动维护该编辑要素对象的空间索引,那么就会耗费一定的服务器资源,特别是在大数据量进行数据插入的过程中,无需进行空间索引的创建,可以等批量插入完成之后,统一创建空间索引,这样无疑就提高了操作效率。

    ArcGIS Desktop、ArcToolbox、ArcSDE命令行、Python都提供了管理空间索引的方法,当然ArcGIS Engine也提供了管理空间索引的接口


    IFeatureClassLoad.LoadOnlyMode


    2:如果进行更新操作,就需要留意索引
    用户进行更新,需要先查询出需要更新的要素对象,那么不管是通过属性索引或者空间索引进行查询,都需要这些索引对象有效。
    而且在编辑完毕之后,还需要对这些索引对象重新创建,保证新编辑对象的索引更新。

    3:数据库归档日志关闭
    如果是大数据量插入操作,如果没有特殊要求,可以将Oracle的归档日志进行关闭,因为归档日志主要记录数据的更高,特别是数据的修改和删除,对数据新增操作其实无需打开数据库归档,如果打开,系统会在批量新增数据的同时,写入大量的归档日志信息,也无疑也会降低编辑效率。

    4:禁用表空间日志
    虽然数据库的归档日志禁用之后,只是说数据库不再产生具体的归档日志文件,但是还需要进行非归档的循环日志写入,那么如果完全禁用日志的生成,需要禁用操作用户的表空间日志,这样在插入数据之后,系统就会记录比较少的日志信息。

    启用日志(Logging):用户进行表创建、索引创建、分区以及后续插入等操作产生REDO日志,作为数据恢复的依据。

    禁用日志(No Logging):以上相关操作不会产生REDO日志,进而也不能进行数据恢复,但是数据加载效率会大幅度提高。



    注意:这些操作是用户进行大数据量新增条件下,而且具有Oracle数据库知识的用户操作。

    操作示例:

    1:禁用归档日志

    sqlplus / as sysdba

    shutdown immediate;

    startup mount;

    alter database flashback off;

    alter database noarchivelog;

    alter database open;

    select flashback_on from v$database;

    archive log list;


    2:禁用表空间日志

    sqlplus /nolog

    connect / as sysdba;

    select 'ALTER TABLESPACE ' || CHR(34) || NAME || CHR(34) || 'NOLOGGING;'

    FROM V$TABLESPACE

    WHERE NAME NOT IN ('SYSTEM','SYSAUX','USERS','TEMP','UNDOTBS1')ORDER BY NAME;

     

    ALTER TABLESPACE "PM_BDATA" NOLOGGING;

    ALTER TABLESPACE "PM_BINDEX" NOLOGGING;

    ALTER TABLESPACE "PM_BDATA_TOPO" NOLOGGING;


    3:当用户只需完毕之后,在进行表空间日志启用和归档日志的启用即可。

    4:启用表空间日志

    sqlplus /nolog

    connect / as sysdba;

    select 'ALTER TABLESPACE ' || CHR(34) || NAME || CHR(34) || 'LOGGING;'

    FROM V$TABLESPACE

    WHERE NAME NOT IN ('SYSTEM','SYSAUX','USERS','TEMP','UNDOTBS1')ORDER BY NAME;

    ALTER TABLESPACE "PM_BDATA" LOGGING;

    ALTER TABLESPACE "PM_BINDEX" LOGGING;

    ALTER TABLESPACE "PM_BDATA_TOPO" LOGGING;


    5:启用归档日志

    sqlplus / as sysdba

    alter system set db_recovery_file_dest_size=10G scope=spfile;

    alter system setdb_recovery_file_dest='C:\oradata\flash_recovery_area' scope=spfile;

    alter system setlog_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST' scope=spfile;

    shutdown immediate;

    startup mount;

    alter database archivelog;

    alter database flashback on;

    alter database open;

    select flashback_on from v$database;

    archive log list;


    5:版本编辑的状态压缩

    这个问题我就不再赘述了,该博客无数次提及这个问题,感兴趣的用户可以在本博客搜索“版本压缩”或者“Compress”。


    6:Oracle参数

    比如足够大的SGA和PGA,典型Oracle参数的设置如Open_Cusors、db_writer_processes等


    7:其他因素

    当然,如果用户的硬件环境足够好,比如数据与索引分开存储、分区表、RAC架构等也会为批量写入数据提高效率。

    注意;严格禁止用户在OLTP环境下使用Oracle的并行计算,因为这样会严重造成资源占用问题。



    ----------------------------------------------------------------------------------

    版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

    Blog:               http://blog.csdn.net/linghe301

    ----------------------------------------------------------------------------------


    展开全文
  • 延时测试(备份库执行) alter database recover managed standby database delay 120 disconnect from session; 实时同步 ALTER ...
    延时测试(备份库执行)
    alter database recover managed standby database delay 120 disconnect from session;   


    实时同步
    ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;

    来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30345407/viewspace-2144504/,如需转载,请注明出处,否则将追究法律责任。

    转载于:http://blog.itpub.net/30345407/viewspace-2144504/

    展开全文
  • 具体描述如下,同一份数据处理最后并写入数据库的代码,在eclipse里面执行能及时的在oracle表里面查看到插入的数据,但是打成可执行的jar包在linux下有java -jar 去执行需要十五到二十分钟才能看到数据。很是郁闷,...
  • 这对于Oracle数据库中任何更改活动的性能调整都很重要,因为使用默认提交设置,提交更改的前台会话将在等待事件“日志文件同步”中等待,该事件是等待日志编写器活动,其中,等待事件“日志文件并行写入”始终是IO...

    这篇文章是关于如何测量“日志文件并行写入”事件的时间。这对于Oracle数据库中任何更改活动的性能调整都很重要,因为使用默认提交设置,提交更改的前台会话将在等待事件“日志文件同步”中等待,该事件是等待日志编写器活动,其中,等待事件“日志文件并行写入”始终是IO所用时间的指示器。

    日志文件同步

    首先:前台会话通常在提交等待日志编写器将其更改向量写入联机重做日志文件时等待等待事件“日志文件同步”。总是假设会出现“日志文件同步”是错误的。如果日志编写器设法将磁盘上的SCN增加到前台会话的提交SCN或超出该SCN,则不会出现“日志文件同步”等待事件。

    我发现没有“日志文件同步”等待事件,因为我人为地降低了提交会话的速度。然而,随着Oracle代码的并行性的改进,甚至随着硬件层降低写延迟(特别是持久内存)的改进,这种情况在不久的将来可能会出现。至少11.2.0.4和更高版本是这样的(可能更早,但这些是我验证过的版本)。

    日志文件并行写入

    然而,这篇文章是关于在很多情况下导致“日志文件同步”时间的罪魁祸首的事件:它是关于“日志文件并行写入”等待事件,该事件发生在日志编写器中(当日志编写器本身写入时,它可以将其委托给日志编写器工作进程LGnn),这通常由Oracle数据库调谐器进行测量,以验证在前台会话显示高“日志文件同步”等待指示正在等待日志编写器的情况下日志编写器IO延迟。

    我在查看logwriter的代码路径,使用intel pin tool s的“调试跟踪”工具,并在Linux、非ASM、Oracle 19.5上使用Tanel Poder的snaper,在logwriter进程上使用开始和结束快照。我将log writer设置为single logwriter模式(“_use_single_logwriter”=true),并执行了redo,这肯定会被logwriter接收。

    在那里,我注意到统计数据表明发生了写操作,而没有“日志文件并行写入”等待事件。很奇怪…所以我深入研究了功能发生的情况。这些是我找到的函数:https://gitlab.com/snippets/1926207

    重要的是:

    –在函数ksfdaio()中提交IO请求:

    ksfdaio>ksfdgo>ksfd_skgfqio>skgfqio>skgfr_lio_listio64>io_submit

    –并在函数ksfdblock()中读取IO请求结果(“reaped”):

    ksfdblock>ksfdpoll>ksfdwtio>skgfrwat>skgfrliopo>io-getevents

    但根本不叫等待事件!*

    与早期版本相比,这是一个明显的变化,在早期版本中,日志编写器写入始终会产生“日志文件并行写入”等待事件。但这种变化是什么时候发生的?为了回答这个问题,我安装了版本12.1.0.2(没有补丁)来查看代码路径,找到了:https://gitlab.com/snippets/1926211

    重要的是:

    –调用wait接口:kslwtbctx()

    –在函数ksfdgo()中提交IO请求:

    ksfd_sbio>ksfdgo>ksfd_skgfqio>skgfqio>skgfr_lio_listio64>io_submit

    –并在函数ksfdwtio()中读取IO请求结果(“reaped”):

    ksfd_sbio>ksfdwtio>skgfrwat>skgfospo>skgfrliopo>io_getevents

    –等待接口结束:kslwtectx()

    啊!所以一个明显的变化!那么这种变化是什么时候发生的呢?我安装了12.2.0.1,找到了相同的“等待”代码路径,然后安装了18.3,找到了等待的代码路径。所以变化可能发生在甲骨文19!所以我安装了19.3,再次找到了等待的代码路径!!那是PSU 19.4还是19.5的变化?我安装了19.5,也找到了等待的代码路径。

    O.M.G.为什么我在同一版本的两个数据库中看到不同的行为?好吧,我设置了一些未记录的参数,所以我在新安装的数据库中复制了这些参数……它没有改变。

    还有什么不同?嗯…一个是多租户数据库,另一个不是…但这肯定不会改变IO代码路径??当然这很容易检查,所以我删除了非CDB数据库并创建了一个CDB数据库,现在它显示了相同的“非等待”代码路径。

    因此,显然,在多租户模式下使用oracle数据库会改变IO代码路径行为。我检查了版本中的代码路径,发现这个变化出现在12.2.0.1.0中,所以本质上是在Oracle12.2中(Oracle18和19实际上是Oracle12.2.0.2和Oracle12.2.0.3)。为了澄清这一点:我在12.1.0.2中没有发现这个变化。

    这是否意味着等待事件“日志文件并行写入”根本不显示?不,如果io_提交后的调用io_getevents未返回所有提交的io,则它必须等待,此时调用等待接口,然后进入阻塞io_getevents调用,因此实际等待是计时的。此代码片段显示如下:https://gitlab.com/snippets/1926212

    这将显示 ksfdblock>ksfdpoll>ksfdwtio>skgfrwat>skgfrliopo>io getevents,返回0(这意味着它在完成队列中找不到任何IOs),然后返回ksfdpoll函数,调用等待接口kslwtbctx,然后再次潜水到io u getevents,但现在处于阻塞模式等待io。

    我还重复了对ASM的测试,它显示了完全相同的(非)等待行为。

    结束语

    对于Oracle版本12.1.0.2直至19.5,等待事件“日志文件并行写入”既包括IO请求的提交(io_submit调用),也包括等待所提交的IO完成(io_getevents调用)。这意味着在这种情况下,事件的等待时间是IO请求的总延迟,包括操作系统处理。

    从版本12.2开始,仅在使用多租户选项的情况下进行更改,并且仅在提交的IO在提交后不可用时才显示等待事件“日志文件并行写入”,因此日志记录器进程具有等待他们。如果显示了等待,则事件的时间是从日志记录器过程的角度来看,IO完成的实际等待时间,而不是IO延迟时间。

    当然,如果磁盘上具有不同延迟的多个日志组,则此等待事件将等待所有IO完成,这意味着它将乘以所有提交的IO中最慢的IO的时间。

    展开全文
  • Oracle 11gR2新特性--延迟段创建(Deferred Segment Creation) 真题1、什么是延迟段创建(Deferred Segment Creation)? 答案:在Oracle 11.2中,当创建一个空表或者空分区时,为了加快创建速度,...
    Oracle 11gR2新特性--延迟段创建(Deferred Segment Creation)




    真题1、 什么是延迟段创建(Deferred Segment Creation)?

    答案:在Oracle 11.2中,当创建一个空表或者空分区时,为了加快创建速度,Oracle并不会立即分配初始段和空间,实际的表段(Table Segement)被延迟到第一行数据插入时创建。延迟段创建特性通过DEFERRED_SEGMENT_CREATION参数控制,默认为TRUE,表示开启该功能。延迟段创建可以节省空间,加快初始化过程,是面向性能和资源的一个优化。可以通过修改参数DEFERRED_SEGMENT_CREATION来关闭这个特性:

    ALTER SYSTEM SET DEFERRED_SEGMENT_CREATION=FLASE;

    该参数为动态参数,不需要重启数据库。可以通过如下的SQL语句找到所有的空表(未分配任何区的表):

    SELECT SEGMENT_CREATED,TABLE_NAME FROM USER_TABLES WHERE SEGMENT_CREATED = 'NO';

    延迟段创建的限制条件有:

    ① 延迟段创建不支持的表类型包括:索引组织表(Index-Organized Tables)、簇表(Clustered Tables)、全局临时表(Global Temporary Tables)、会话级临时表(Session-Specific Temporary Tables)、内部表(Internal Tables)、Typed表(Typed Tables)、AQ表(AQ Tables)和外部表(External Tables)。

    ② 用户SYSSYSTEMPUBLICOUTLNXDB下的表不支持延迟段创建。

    ③ 延迟段创建不支持位图连接索引(Bitmap Join Indexes)和域索引(Domain Indexes)。

    ④ 延迟段创建不支持字典管理表空间(Dictionary-Managed TablespaceDMT

    ⑤ 延迟段创建不支持SYSTEM表空间。

    ⑥ 延迟段创建从Oracle 11.2.0.2版本开始才开始支持分区和子分区。

    在创建表的时候,当SEGEMENT CREATIONIMMEDIATE时,Oracle会为表建立段(SEGMENT),当SEGEMENT CREATIONDEFERRED时,Oracle不会为空表建立段,如下所示:

    SQL> CREATE TABLE T_TEST_2(ID NUMBER,NAME VARCHAR2(10)) SEGMENT CREATION IMMEDIATE;

    表已创建。

    SQL> CREATE TABLE T_TEST_3(ID NUMBER,NAME VARCHAR2(10)) SEGMENT CREATION DEFERRED;

    表已创建。

    SQL> SELECT SEGMENT_NAME FROM USER_SEGMENTS WHERE SEGMENT_NAME LIKE 'T_TEST%';

    SEGMENT_NAME

    -------------

    T_TEST_2

    SQL> INSERT INTO T_TEST_1 VALUES(1,'LHRDB');

    已创建 1 行。

    SQL> SELECT SEGMENT_NAME FROM USER_SEGMENTS WHERE SEGMENT_NAME LIKE 'T_TEST%';

    SEGMENT_NAME

    ------------

    T_TEST_1

    T_TEST_2

    可以看到,在SEGEMENT CREATIONIMMEDIATE的情况下,OracleT_TEST_2建立了段,在SEGEMENT CREATIONDEFERRED的情况下,Oracle没有为表T_TEST_3建立段,当向没有分配段的空表中插入信息时,Oracle会自动为空表建立段。需要注意的是,未分配任何区(EXTENT)的表,在DBA_SEGMENTS视图中是查不到的。若使用不加DROP ALL STROAGETRUNCATE语句,则分配的段只是缩小到最初分配的大小,并没有完全回收段,如下所示:

    SQL> TRUNCATE TABLE TEST1;          ------使用不加子句的truncate

    Table truncated.

    SQL> SELECT SEGMENT_NAME,BYTES FROM USER_SEGMENTS;       -----只是删除到最小的区

    SEGMENT_NAME                        BYTES

    ------------------------------ ----------

    TEST1                               65536

    SQL> TRUNCATE TABLE TEST1 DROP ALL STORAGE;         -----使用11g中新加的子句drop all stroage

    Table truncated.

    SQL> SELECT SEGMENT_NAME,BYTES FROM USER_SEGMENTS;      -----段全部被回收

    no rows selected

    需要关注的是,这个新特性会带来一个问题:在使用exp/imp进行导出导入时,不会包含这些空表(数据泵expdp不存在这个问题,expdp可以导出空表),所以,在迁移数据的时候可能会导致遗漏部分空表。针对这个问题的解决方法有:

    1、最原始最笨的办法(不推荐):INSERT一行,再ROLLBACK或者删除就可以产生SEGMENT了。该方法是在空表中插入数据,再删除,则会产生SEGMENT,此时再导出时就可以导出空表。

    2、设置DEFERRED_SEGMENT_CREATION参数。设置DEFERRED_SEGMENT_CREATION参数为FALSE来禁用“延迟段创建”,无论是空表还是非空表,都会分配SEGMENT。需要注意的是,该值设置后只对后面新增的表产生作用,对之前建立的空表(已经存在的)不起作用,仍不能导出。

    3、使用ALLOCATE EXTENT。使用ALLOCATE EXTENT可以为数据库的每一张表分配EXTENT。批量生成脚本:

    SELECT 'ALTER TABLE '||D.OWNER||'.'||D.TABLE_NAME||' ALLOCATE EXTENT;' EXEC_SQL FROM DBA_TABLES D WHERE D.SEGMENT_CREATED='NO' AND D.OWNER IN ('LHR','ABC'); --注意修改用户名

    执行以上SQL产生的脚本后即可为每一个空表分配段,然后执行exp命令即可。

    总结一下,在Oracle 11.2中,当采用exp导出数据时,最好先判断数据库中是否含有空表。当有空表时,先设置参数DEFERRED_SEGMENT_CREATIONFALSE,然后使用ALLOCATE EXTENT为每一个空表分配段,最后再导出所需要的数据。


    另外,对于分区表而言,即使没有创建段(无论是整个分区还是个别子分区没有创建段),若使用exp进行导出则也不存在丢失分区表或丢失某个子分区的问题。






    http://docs.oracle.com/cd/E11882_01/server.112/e22490/whatsnew.htm#SUTIL2871

    Original Export

    • In Oracle Database 11g release 2 (11.2), the DEFERRED_SEGMENT_CREATION parameter is set to TRUE by default. This means that any tables you create do not have any segments until the first row of data is inserted into the table. Original Export ignores tables without segments. Therefore, if you create any new tables and do not insert any data before performing an export, those tables are not exported. (Note that Data Pump Export does not have this limitation because it does not ignore tables without segments.)





    DEFERRED_SEGMENT_CREATION

    Property Description
    Parameter type Boolean
    Default value true
    Modifiable ALTER SESSION, ALTER SYSTEM
    Range of values true | false
    Basic No

    DEFERRED_SEGMENT_CREATION specifies the semantics of deferred segment creation. If set to true, then segments for tables and their dependent objects (LOBs, indexes) will not be created until the first row is inserted into the table.

    Before creating a set of tables, if it is known that a significant number of them will not be populated, then consider setting this parameter to true. This saves disk space and minimizes install time.


    Restrictions on Deferred Segment Creation This clause is subject to the following restrictions:

    • You cannot defer segment creation for the following types of tables: index-organized tables, clustered tables, global temporary tables, session-specific temporary tables, internal tables, typed tables, AQ tables, external tables, and tables owned by SYS, SYSTEM, PUBLIC, OUTLN, or XDB.

    • Deferred segment creation is supported on partitions and subpartitions beginning with Oracle Database 11g Release 2 (11.2.0.2).

    • Deferred segment creation is not supported for bitmap join indexes and domain indexes.

    • Deferred segment creation is not supported in dictionary-managed tablespaces.

    • Deferred segment creation is not supported in the SYSTEM tablespace.

    • Serializable transactions do not work with deferred segment creation. Trying to insert data into an empty table with no segment created causes an error.

    See Also:

    Oracle Database Concepts for general information on segment allocation and Oracle Database Reference for more information about the DEFERRED_SEGMENT_CREATION initialization parameter





      下面测试Oracle 11g开始的新特性truncate的增强和延迟段空间创建。
      Oracle从11g开始,当用户创建一张空表的时候不会先分配段和空间,只有当对这张表插入第一行数据的时候才分配段和空间。
      这就解决了有很多表是空的但是占用大量的磁盘空间。
      测试11g延迟段创建和truncate
      用户下有一张新表
      复制代码
      SQL> select * from tab;
      TNAME                          TABTYPE  CLUSTERID
      ------------------------------ ------- ----------
      TEST1                          TABLE
      SQL> select segment_name,bytes from user_segments;        ----还没有给分配空间
      no rows selected
      SQL> insert into test1 select * from dba_objects where rownum<2;     -----插入一行记录
      1 row created.
      SQL> select segment_name,bytes from user_segments;       ----分配空间
      SEGMENT_NAME                        BYTES
      ------------------------------ ----------
      TEST1                               65536
      SQL> commit;
      Commit complete.
      SQL> alter table test1 allocate extent;          ------手动给表分配一个区
      Table altered.
      SQL> select segment_name,bytes from user_segments;
      SEGMENT_NAME                        BYTES
      ------------------------------ ----------
      TEST1                              131072
      SQL> truncate table test1;          ------使用不加子句的truncate
      Table truncated.
      SQL> select segment_name,bytes from user_segments;       -----只是删除到最小的区
      SEGMENT_NAME                        BYTES
      ------------------------------ ----------
      TEST1                               65536
      SQL> truncate table test1 drop all storage;         -----使用11g中新加的子句drop all stroage
      Table truncated.
      SQL> select segment_name,bytes from user_segments;      -----段全部被回收
      no rows selected


    很多数据库都有存在空表的情况,较多的空表会占用大量的磁盘空间,ORACLE 11gR2版本推出延迟段创建新特性,所谓延迟段创建,顾名思义就是在创建一张新空表的时候,ORACLE默认不会为这张空表分配段(SEGMENTS),也就是不会为这张空表分配空间,这样就避免了空表占用空间的情况,如下实验:

    SQL> SELECT * FROM V$VERSION;

    BANNER

    ----------------------------------------------------------------------

    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

    PL/SQL Release 11.2.0.1.0 - Production

    CORE    11.2.0.1.0      Production

    TNS for 32-bit Windows: Version 11.2.0.1.0 - Production

    NLSRTL Version 11.2.0.1.0 - Production

    SQL> CREATE TABLE T_TEST_1(ID NUMBER,NAME VARCHAR2(10));

    表已创建。

    SQL> SELECT SEGMENT_NAME FROM USER_SEGMENTS WHERE SEGMENT_NAME='T_TEST_1';

    未选定行

        默认情况下ORACLE没有为空表(T_TEST_1)分配空间,如果查看过ORACLE11gR2官方文档关于CREATE TABLE语法的人可能会看到SEGEMENT CREATION信息,如下:
    img_8b46f61c6c7ece0246e3c143502d9ad8.jpg

    SEGEMENT CREATIONIMMEDIATE的情况下,ORACLE在建表的时候,会为表建立段(SEGMENTS),当SEGEMENT CREATIONDEFERRED的情况下,ORACLE不会为空表建立段,下面分别演示下这两种情况的效果。

    SQL> CREATE TABLE T_TEST_2(ID NUMBER,NAME VARCHAR2(10))

    2  SEGMENT CREATION IMMEDIATE;

    表已创建。

    SQL> CREATE TABLE T_TEST_3(ID NUMBER,NAME VARCHAR2(10))

      2  SEGMENT CREATION DEFERRED;

    表已创建。

    SQL> SELECT SEGMENT_NAME FROM USER_SEGMENTS WHERE SEGMENT_NAME LIKE'T_TEST%';

    SEGMENT_NAME

    -------------

    T_TEST_2

        可以看到,在SEGEMENT CREATIONIMMEDIATE的情况下,ORACLET_TEST_2建立了段,在SEGEMENT CREATIONDEFERRED的情况下,ORACLE没有为表T_TEST_3建立段,当向没有分配段的空表中插入信息时,ORACLE会自动为空表建立段。

    SQL> INSERT INTO T_TEST_1 VALUES(1,'STREAM');

    已创建 1 行。

    SQL> SELECT SEGMENT_NAME FROM USER_SEGMENTS WHERE SEGMENT_NAME LIKE'T_TEST%';

    SEGMENT_NAME

    ------------

    T_TEST_1

    T_TEST_2

        也可以用ALLOCATE EXTENT的方式来为空表建立段信息。

    SQL> ALTER TABLE T_TEST_3 ALLOCATE EXTENT;

    表已更改。

    SQL> SELECT SEGMENT_NAME FROM USER_SEGMENTS WHERE SEGMENT_NAME LIKE'T_TEST%';

    SEGMENT_NAME

    ------------

    T_TEST_1

    T_TEST_2

    T_TEST_3

        虽然延迟段创建避免了空表占用空间的问题,但是也为DBA带点小麻烦,这就是在EXP导出数据的时候,虽然空表的信息也存在数据库字典内,但是ORACLE不会导出未分配段的空表,这样在使用EXP做数据迁移的时候,就会遇到点小问题。

    SQL> CREATE USER dbdream IDENTIFIED BY dbdream DEFAULT TABLESPACE USERS;

    用户已创建。

    SQL> GRANT CONNECT,RESOURCE TO DBDREAM;

    授权成功。

    SQL> CREATE TABLE T_TEST_1(ID NUMBER,NAME VARCHAR2(10));

    表已创建。

    SQL> CREATE TABLE T_TEST_2(ID NUMBER,NAME VARCHAR2(10))

    2  SEGMENT CREATION IMMEDIATE;

    表已创建。

    D:\ >exp dbdream/dbdream file=d:\dbdream.dmp

    Export: Release 11.2.0.1.0 - Production on 星期一 2 13 11:35:22 2012

    Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

    连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

    With the Partitioning, OLAP, Data Mining and Real Application Testing options

    已导出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集

    即将导出指定的用户...

    ...

    . . 正在导出表                        T_TEST_2导出了           0 

    ...

    成功终止导出没有出现警告。

        EXP只能导出已经分配段的表,要导出未分配段的空表EXP就无能为力了,要导出未分配段的空表就需要使用数据泵(EXPDP),使用EXPDP可以导出未分配段的空表。

    SQL> CREATE DIRECTORY D_TEST AS 'D:\T_TEST';

    目录已创建。

    SQL> GRANT READ,WRITE ON DIRECTORY D_TEST TO DBDREAM;

    授权成功。

    D:\ >expdp dbdream/dbdream directory=D_TEST dumpfile=dbdream.dmp

    Export: Release 11.2.0.1.0 - Production on 星期一 2 13 11:50:00 2012

    Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

    连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

    With the Partitioning, OLAP, Data Mining and Real Application Testing options

    正在使用 BLOCKS 方法进行估计...

    ...

    . . 导出了 "DES"."T_TEST_1"                                0 KB       0 

    . . 导出了 "DES"."T_TEST_2"                                0 KB       0 

    ...

    作业 "DES"."SYS_EXPORT_SCHEMA_01" 已于 11:50:47 成功完成

        如果非要用EXP做迁移,而且所有空表也都需要迁移,那么就需要使用上文提到的利于ALLOCATE EXTENT创建段的方法。在做EXP操作之前,先使用ALLOCATE EXTENT的方法为空表分配段信息。

    SQL> DECLARE

      2  V_COUNT NUMBER;

      3  BEGIN

      4  FOR I IN (SELECT TABLE_NAME FROM USER_TABLES) LOOP

      5  EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || I.TABLE_NAME INTO V_COUNT;

      6  IF V_COUNT = 0 THEN

      7  EXECUTE IMMEDIATE 'ALTER TABLE ' || I.TABLE_NAME || ' ALLOCATE EXTENT';

      8  END IF;

      9  END LOOP;

     10  END;

     11  /

    PL/SQL 过程已成功完成。

    SQL> SELECT SEGMENT_NAME FROM USER_SEGMENTS WHERE SEGMENT_NAME LIKE'T_TEST%';

    SEGMENT_NAME

    ------------

    T_TEST_1

    T_TEST_2

        然后在用EXP导出数据,这样空表就可以被导出了。

    D:\ >exp dbdream/dbdream file=d:\dbdream.dmp

    Export: Release 11.2.0.1.0 - Production on 星期一 2 13 11:58:03 2012

    Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

    连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

    With the Partitioning, OLAP, Data Mining and Real Application Testing options

    已导出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集

    即将导出指定的用户...

    ...

    . . 正在导出表                          T_TEST导出了           0 

    . . 正在导出表                        T_TEST_2导出了           0 

    ...

    成功终止导出没有出现警告。

     



    ORACLE 11g 用exp命令导出库文件备份时,发现只能导出来一部分表而且不提示错误,之前找不到解决方案只能把没导出来的表重新建建立。后来发现是所有的空表都没有导出来。于是想好好查查,因为在以前的10g版本中没有这样的问题。

    查资料发现Oracle 11g中有个新特性:新增了一个参数“deferred_segment_creation”含义是段延迟创建,默认是true。

    具体是什么意思呢?

    如果这个参数设置为true,你新建了一个表Table1,并且没有向其中插入数据,那么这个表不会立即分配extent,也就是不占数据空间,即表也不分配 segment 以节省空间,所以这些表也没能导出来。在系统表user_tables中也可以看到segment_treated的字段里是“NO”或者“YES”说明了某张表是否分配了segment。说白了是为了可以节省少量的空间。

     

    用下面的SQL语句查询,可以发现没有导出的表其 segment_created 字段值都是 'NO'。

    Select segment_created,table_name from user_tables where segment_created = 'NO';

     

    解决方法:

    1、最原始最笨的办法(不推荐):insert一行,再rollback或者删除就产生segment了。

    该方法是在在空表中插入数据,再删除,则产生segment。导出时则可导出空表。

     

    2、设置deferred_segment_creation 参数:

       设置deferred_segment_creation 参数为FALSE来禁用"段推迟创建"(也就是直接创建segment),无论是空表还是非空表,都分配segment。

       在sqlplus中,执行如下命令:

       SQL>alter system set deferred_segment_creation=false;

       查看:

       SQL>show parameter deferred_segment_creation;

       注意:该值设置后只对后面新增的表产生作用,对之前建立的空表(已经存在的)不起作用,仍不能导出。

       并且要重新启动数据库,让参数生效。

     

    3、使用ALLOCATE EXTENT,可以导出之前已经存在的空表。

       使用ALLOCATE EXTENT可以为数据库对象的每一张表分配Extent(注意针对每一张表,就是说一张表需要一条SQL代码):

       其语法如下:

       -----------

       ALLOCATE EXTENT { SIZE integer [K | M] | DATAFILE 'filename' | INSTANCE integer }

       -----------

       可以针对数据表、索引、物化视图等手工分配Extent。

       ALLOCATE EXTENT使用样例:

        ALLOCATE EXTENT

        ALLOCATE EXTENT(SIZE integer [K | M])

        ALLOCATE EXTENT(DATAFILE 'filename')

        ALLOCATE EXTENT(INSTANCE integer)  www.2cto.com

        ALLOCATE EXTENT(SIZE integer [K | M]   DATAFILE 'filename')

        ALLOCATE EXTENT(SIZE integer [K | M]   INSTANCE integer)

       针对数据表操作的完整语法如下:

       -----------

       ALTER TABLE [schema.] table_name ALLOCATE EXTENT [({ SIZE integer [K | M] | DATAFILE 'filename' | INSTANCE integer})]

       -----------

       故,需要构建如下样子简单的SQL命令:

       -----------

       alter table TableName allocate extent

       -----------

       但要是每一张表写一条语句的话太过麻烦,为了方便我们使用SQL命令拼写出每一张表的alter语句。

     

    构建对空表分配空间的SQL命令。

       查询当前用户下的所有空表(一个用户最好对应一个默认表空间)。命令如下:

       SQL>select table_name from user_tables where NUM_ROWS=0; 

       根据上述查询,可以构建针对空表分配空间的命令语句,如下:

       SQL>Select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0 or num_rows is null(注意:很多教程没有这里,这里是有可能位空的)

       上述代码可产生批量的修改表extent的SQL语句(有多少张空表就产生多少条),我们只需要将其生成的所有sql代码全部执行,就可以给每一张已经存在的表来分配segment,就OK了。

     

    最后:这时再用exp导出就没有问题了。但是:数据库本身的deferred_segment_creation属性还是TRUE,也是就是说如果再创建新表的话,默认还是不分配segment的。所以还是需要更改deferred_segment_creation的参数,以便以后创建的新表自动分配segment。

    总结:

        如果你的数据库还没有创建任何数据表,那么直接修改deferred_segment_creation属性,以后创建的表无论是不是为空都会自动分配segment,就不会出现导不出空表的情况。然而如果你的数据库中已经有很多空表,并且需要导出来,那么光修改deferred_segment_creation属性则没有用的,因为它只对之后创建的表有作用。你需要给已存在的空表分配segment以便可以导出存在的空表,就用到上面讲的allocate extent方法,但此方法只针对已经存在的表的segment属性,所以最好就是:先给已存在的空表分配segment,方便其可以直接导出,然后设定deferred_segment_creation参数以便以后每张表无论是否为空都自动分配segment。

     

    附录有关第三种方法给已经存在的空表分配segment,下面介绍一种生成脚本来执行sql的方法。

    SQL>Select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0 or num_rows is null;

    批量输出上述生成的SQL语句并写入到一个.sql的脚本文件中。

    如: 

    1. 创建执行脚本文件:我创建一个E:\sql_script.sql文件。内容如下:

       set heading off;

       set echo off;

       set feedback off;

       set termout on;

       spool E:\sql_allocate.sql;

       Select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0or num_rows is null;

       spool off;

       这个脚本的作用就是创建一个E:\sql_allocate.sql脚本文件,将Select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0 or num_rows is null的执行结果(就是给每张表生成segment的SQL代码)批量输出,存储到一个E:\sql_allocate.sql的脚本文件中。

     

    2. 执行E:\sql_script.sql文件来生成“分配表空间的SQL代码”的脚本文件sql_allocate.sql。

       命令如下:

       SQL>@ E:\sql_script.sql;  (也可写一个批处理文件,命令如下:sqlplus 用户名/密码@数据库 @E:\sql_script.sql)

       执行完毕后,得到E:\sql_allocate.sql脚本文件(里面是给所有空表分配segment的SQL代码)。 

       打开该文件会看到,已经得到对所有空表分配空间的SQL语句。

     

    3. 执行E:\sql_allocate.sql文件来对表分配空间。

       命令如下:SQL>@ E:\sql_allocate.sql

       执行完毕,表已更改。之前存在的空表已分配segment空间!

     

    大功告成,此时执行exp命令,即可把包括空表在内的所有表,正常导出。



    11.2 Database New Feature Deferred Segment Creation [Video] (文档 ID 887962.1)


    类型:
    状态:
    上次主更新:
    上次更新:
    BULLETIN
    PUBLISHED
    2013-12-6
    2016-8-6

    In this Document

    Purpose
    Scope
    Details
    References


    APPLIES TO:

    Oracle Database - Enterprise Edition - Version 11.2.0.1 to 11.2.0.1 [Release 11.2]
    Information in this document applies to any platform.

    PURPOSE

    This bulletin provides information about the database version 11.2 new feature called Deferred Segment Creation also referred to as Segment Creation On-Demand.

    SCOPE

    Database Administrators and Developers.

    DETAILS

    downloadattachmentprocessor?parent=DOCUM Video - 11.2 New Feature Deferred Segment Creation (10:04) downloadattachmentprocessor?parent=DOCUM

    The Oracle Database 11.2 includes a new space allocation method. When you create a non-partitioned heap table, the table segment creation is deferred to the first row insert. This functionality is enabled by default with the initialization parameter DEFERRED_SEGMENT_CREATION  set to TRUE.

    The advantages of this new space allocation method are:

    ? A significant amount of disk space can be saved for applications that create hundreds or thousands of tables upon installation, many of which might never be populated.

    ? The application installation time is reduced, because the creation of a table is a data dictionary operation only.

    When you insert the first row into the table, the segments are created for the base table, its LOB columns, and its indexes. During segment creation, cursors on the table are invalidated. These operations have a small additional impact on performance.

    Note: With this new allocation method, it is essential that you do proper capacity planning so that the database has enough disk space to handle segment creation when tables are populated. For more details, see the Oracle Database Administrator's Guide.

    SQL> connect / as sysdba
    Connected.

    SQL> show parameter deferred

    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    deferred_segment_creation            boolean     TRUE


    SQL> connect imran/imran
    Connected.

    SQL> create table  t1(no number);

    Table created.

    SQL> select * from user_segments;

    no rows selected


    SQL> insert into t1 values(10);

    1 row created.

    SQL> commit;

    Commit complete.



    SQL> select segment_name from user_segments;

    SEGMENT_NAME
    --------------------------------------------------------------------------------
    T1

    SQL> select table_name,segment_created from user_tables;

    TABLE_NAME                     SEG
    ------------------------------ ---
    T1                             YES


    ? This slide shows you how to verify the segment creation on demand. First you check the parameter DEFERRED_SEGMENT_CREATION . Then a table is created without segments, which you can verify by querying the USER_SEGMENTS data dictionary view. After the insert of a row, you query this view again, to see that the segment now exists.

    ? You can also query the SEGMENT_CREATED column of the USER_TABLES, USER_INDEXES, or USER_LOBS views. For non-partitioned tables, indexes and lobs, this column shows YES, if the segment is created. Note that when you create a table with deferred segment creation (the default), the new table appears in the *_TABLES views, but no entry for it appears in the *_SEGMENTS views until you insert the first row.

    ? Another addition to the data dictionary is the SYS.SEG$ table that stores the storage parameters which you specified during the table or index creation.

    You can control segment creation in two ways:

    1) With the DEFERRED_SEGMENT_CREATION initialization parameter set to TRUE or FALSE. This parameter can be set in the initialization file. You can also control it via the ALTER SESSION or ALTER SYSTEM commands.

    Example:

    SQL> connect / as sysdba
    Connected.
    SQL> show parameter def

    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    deferred_segment_creation            boolean     TRUE
    SQL> alter system set deferred_segment_creation=FALSE;

    System altered.

    SQL> show parameter def

    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    deferred_segment_creation            boolean     FALSE

    SQL> connect imran/imran
    Connected.

    SQL> create table t2(no number);

    Table created.

    SQL> select segment_name from user_segments;

    SEGMENT_NAME
    --------------------------------------------------------------------------------
    T2

    SQL> alter session set deferred_segment_creation=true;

    Session altered.

    SQL> create table t3( no number);

    Table created.

    SQL> select segment_name from user_segments;

    SEGMENT_NAME
    --------------------------------------------------------------------------------
    T2

    SQL>





    2) With the SEGMENT CREATION clause of the CREATE TABLE command:

    SEGMENT CREATION DEFERRED: If specified, segment creation is deferred until the first row is inserted into the table. This is the default behavior for the Oracle Database 11gR2.

    SEGMENT CREATION IMMEDIATE: If specified, segments are materialized during table creation. This is the default behavior in Oracle databases prior to the Oracle Database 11gR2.

    Example


    SQL> select * from user_segments;

    no rows selected

    SQL> CREATE TABLE SEG_TAB3(C1 number, C2 number)
    SEGMENT CREATION IMMEDIATE;  

    Table created.

    SQL> select segment_name from user_segments;

    SEGMENT_NAME
    --------------------------------------------------------------------------------
    SEG_TAB3

    SQL>CREATE TABLE SEG_TAB4(C1 number, C2 number)
    SEGMENT CREATION DEFERRED;

    Table created.

    SQL> select segment_name from user_segments;

    SEGMENT_NAME
    --------------------------------------------------------------------------------
    SEG_TAB3

    SQL>


    This clause takes precedence over the DEFERRED_SEGMENT_CREATION parameter.  It is possible to force creation of segments for an already created table with the ALTER TABLE …MOVE command.  However, it is not possible to directly control the deferred segment creation for dependant objects like indexes. They inherit this characteristic from their parent object, in this case, the table.

    Restrictions and Exceptions :-

    ?To enable deferred segment creation, compatibility must be set to '11.2.0' or higher. 

    ? In the Oracle Database 11.2.0.1, deferred segment creation is restricted to non-partitioned tables and non-partitioned indexes.  Deferred segment creation is not supported for partitioned indexes, bitmap join indexes, and domain indexes. 

    ? IOTs and other special tables like clustered tables, global temporary tables, session-specific temporary tables, internal tables, typed tables, AQ tables, external tables are not supported. Tables owned by SYS, SYSTEM, PUBLIC, OUTLN, and XDB are also excluded.

    ? Segment creation on demand is not supported for tables created in dictionary-managed tablespaces and for clustered tables. If you try creating these tables, segments ARE created.

    ? Also please note: If you create a table with deferred segment creation on a locally managed tablespace, then it has no segments. If at a later time, you migrate the tablespace to dictionary-managed, then any attempt to create segments produces errors. In this case you must drop the table and recreate it.

    Note:

    In Release 11.2.0.1, deferred segment creation is not supported for partitioned tables. This restriction is removed in release 11.2.0.2 and later.

    Notes on Tables Without Segments :-

    The following rules apply to a table whose segment has not yet been materialized: 

    If you create this table with CREATE TABLE ... AS subquery, then if the source table has no rows, segment creation of the new table is deferred. If the source table has rows, then segment creation of the new table is not deferred. 

    If you specify ALTER TABLE ... ALLOCATE EXTENT before the segment is materialized, then the segment is materialized and then an extent is allocated. However the ALLOCATE EXTENT clause in a DDL statement on any indexes of the table will return an error. 

    During an EXCHANGE of a partition or subpartition with a non-partitioned table without a segment, segments are materialized for the non-partitioned table automatically before proceeding with the EXCHANGE. 

    When you issue an ALTER TABLE ... MOVE statement any storage properties you specify override the storage properties specified in the CREATE TABLE statement. 

    In a DDL statement on the table or its LOB columns or indexes, any specification of DEALLOCATE UNUSED is silently ignored. 

    ONLINE operations on indexes of a table without a segment will silently be disabled; that is, they will proceed OFFLINE. 

    Parallel DML operations on tables with no segments are disabled. 


    Additional Automatic Functionality:-


    Additional enhancements in the Oracle Database 11gR2 (unrelated to the deferred segment creation) are implemented to save space: all UNUSABLE indexes and index partitions are created without a segment. This functionality is completely transparent for you. It is enabled by default with the COMPATIBILITY initialization parameter set to 11.2.0.0.

    ? Creating an index without a segment 

    CREATE INDEX test_i1 ON seg_test(c) UNUSABLE; 

    ? Removing any allocated space for an index 

    ALTER INDEX test_i UNUSABLE; 

    ? Creating the segment for an index: 

    ALTER INDEX test_i REBUILD; 


    The following slide shows some SQL commands which you might find useful for this new functionality: 

    ? You can create an index without segment with the CREATE INDEX … UNUSABLE clause. 
    ? You can remove any allocated space with the ALTER INDEX … UNUSABLE clause. 
    ? And finally, you can create a segment for an index with the ALTER INDEX … REBUILD 


    Example

    SQL> select * from user_segments ; 

    no rows selected 

    SQL> create table test_table(no number); 

    Table created. 

    SQL> insert into test_table values(10); 

    1 row created. 

    SQL> commit; 

    Commit complete. 

    SQL> select segment_name from user_segments; 

    SEGMENT_NAME 
    -------------------------------------------------------------------------------- 
    TEST_TABLE 

    SQL> create index test_index on test_table(no) unusable; 

    Index created. 

    SQL> select segment_name from user_segments; 

    SEGMENT_NAME 
    -------------------------------------------------------------------------------- 
    TEST_TABLE 

    SQL> alter index test_index rebuild; 

    Index altered. 

    SQL> select segment_name from user_segments; 

    SEGMENT_NAME 
    -------------------------------------------------------------------------------- 
    TEST_TABLE 
    TEST_INDEX 

    SQL> alter index test_index unusable; 

    Index altered. 

    SQL> select segment_name from user_segments; 

    SEGMENT_NAME 
    -------------------------------------------------------------------------------- 
    TEST_TABLE 

    SQL>

     

    Reference

    Oracle? Database SQL Language Reference 
    11g Release 2 (11.2) 
    Part Number E10592-02









    &

               

    img_e3029f287d989cd04bd75432ecc1c172.png
    DBA笔试面试讲解群1
    DBA笔试面试讲解群2
    欢迎与我联系



    展开全文
  • Oracle基础之Oracle的体系结构

    千次阅读 2015-10-31 16:43:06
    一、Oracle体系结构概述:  Oracle的体系结构是指数据库的组成、工作过程与原理,以及数据在数据库中的组织与管理机制。要了解Oracle数据库的体系结构,必须理解Oracle系统的重要概念和主要组件。  Oracle系统...
  • Oracle 数据库实例介绍

    万次阅读 多人点赞 2018-11-23 15:44:13
    本章介绍 Oracle 数据库实例的原理,实例的参数文件和诊断文件,以及实例创建和数据库的打开与关闭的过程。
  • Oracle 高级教程

    万次阅读 多人点赞 2018-06-06 11:10:15
    目录 一、Oracle体系结构的概览... 2 二、Oracle高级查询... 10 三、Oracle触发器... 18 四、Oracle存储过程... 26 五、Oracle事务... 30 六、Oracle锁... 37 七、Oracle包... 40 八、Oracle游标... 42 九、Oracle...
  • Oracle Undo的学习

    千次阅读 2010-04-16 21:02:00
    当一个事务开始的时候,会首先把变化前的数据和变化后的数据先写入日志缓冲区,然后把变化前的数据写入回滚段,最后才在数据缓冲区中修改(日志缓冲区内容在满足一定的条件后可能被写入磁盘,但在事务提交的时候日志...
  • Oracle自动性能统计

    千次阅读 2017-04-13 10:10:15
    高效诊断性能问题,需要提供完整可用的...Oracle数据库为系统、会话以及单独的sql语句生成多种类型的累积统计信息。本文主要描述Oracle性能统计涉及到的相关概念及统计对象,以更好的利用统计信息为性能调整奠定基础。
  • Oracle RAC

    2013-01-31 09:52:49
    Oracle RAC 目录 RAC 《Oracle RAC》 Oracle RAC组件 展开 RAC 《Oracle RAC》 Oracle RAC组件 展开 编辑本段RAC 〔RAC提供的优缺点〕  Oracle RAC 集群示意图 ...
  • Oracle 第1章 Oracle入门

    2011-04-29 17:05:37
    Oracle 第2章 Oracle查询、数据类型、函数   Oracle 第1章 Oracle入门   注意:本文使用的版本为Oracle 9i 1、技术目标 了解 Oracle 体系结构的各种组件 掌握 Oracle 中的基本用户管理 了解 Oracle ...
  • Oracle 详解Oracle RAC入门和提高

    千次阅读 2014-04-16 14:56:48
    本文将详细讲述Oracle RAC入门和提高,希望对广大Oracle数据库管理人员以及致力于学习Oracle数据库的管理人有所帮助。 Oracle RAC 产品概述 Oracle Real Application Server,真正应用集群,简称Oracle RAC ,...
  • Oracle高级教程

    千次阅读 2018-10-28 10:17:34
    一、OracleOracle体系结构的概览  二、Oracle高级查询 三、Oracle触发器 四、Oracle存储过程 五、Oracle事务 六、Oracle锁 七、Oracle包 八、Oracle游标 九、Oracle函数 十、Oracle备份与...
  • Oracle 体系结构(1)—— Oracle 实例 Oracle Server(Oracle 服务器): 由两部分组成:实例(Instance)+ 数据库(DataBase)。 实例(Instance):是数据库启动时初始化的一组进程和内存结构。一个实例只能对应...
  • Oracle的内存数据库战略

    万次阅读 2016-05-19 10:03:27
    此文简介了Oracle内存数据库的两大分支,TimesTen和Database In-Memory,非常值得一读,两种技术的重要特性完全涵盖,可以让读者很快的对Oracle内存数据库技术的关键点有一个全面的认识,建议看完此文后可以对参考中...
  • Oracle Data Guard 简介

    万次阅读 2009-01-07 11:46:00
    1.Oracle Data Guard概述Oracle在版本7的时候,就支持Standby容灾备份数据库技术,并在Oracle8版本开始支持日志从生产数据库到备用数据库的自动传输。Oracle9i版本把standby技术正式命名为Data Guard。 Data Guard...
  • ORACLE PROCESS

    千次阅读 2012-09-20 00:18:54
    先来看一下Oracle 11g 的架构图。      进程是操作系统中的一种机制,它可执行一系列的操作步。在有些操作系统中使用作业(JOB)或任务(TASK)的术语。一个进程通常有它自己的专用存储区。ORACLE进程的体系...
  • oracle详解

    2021-04-20 17:37:47
    首先看张图: 对于一个数据库系统来说,假设...我们来引入第一个概念,Oracle服务器,所谓Oracle服务器是一个数据库管理系统,它包括一个Oracle实例(动态)和一个Oracle数据库(静态)。Oracle实例是一个运行的概念
  • 全面解析 Oracle Database 20c 数据库技术架构

    千次阅读 多人点赞 2020-11-25 17:52:06
    本文详细介绍了 Oracle Database 20c 数据库的最新技术架构,包括数据库服务器整体架构、数据库实例中的内存和进程结构、数据库文件的物理结构。
  • Oracle block cleanout

    千次阅读 2013-02-22 11:11:25
    简单点说,在oracle的block上都有活动事务的标志的,如果一个事务commit后,由于某些block在commit之前已经写回datafile,或者事务影响到的block数过多,则commit的时候只会清理undo segment header中的事务表信息,...
  • Oracle RAC环境实时数据迁移

    千次阅读 2012-01-06 02:53:15
    Oracle RAC环境实时数据迁移———————————————————————————————————————系统要求及安装前的说明Oracle GoldenGate可以在Oracle不同版本间移动数据,也可以在Oracle和其它...
  • Oracle笔记

    千次阅读 2011-06-30 22:33:00
    Oracle SQL day1 Oracle SQL(Oracle 9i 9.2.0.1.0) 一、DataBase 保存数据,以表的形式表现数据二、SQL SQL(structurequery language 结构化查询语言),是操作关系型数据库中的对象
  • Oracle 物化视图介绍

    千次阅读 2012-09-24 23:57:27
    Oracle的物化视图是包括一个查询结果的数据库对像,它是远程数据的的本地副本,或者用来生成基于数据表求和的汇总表。物化视图存储基于远程表的数据,也可以称为快照。   物化视图可以用于预先计算并保存表...
  • Oracle体系结构

    2018-01-11 16:25:20
    从宏观来讲,我们可以通过查看Oracle数据库数据文件了解其基本物理结构,联系逻辑对应表,大概知晓Oracle逻辑结构。当Oracle数据库启动时,将启动相应进程,加载内存结构,读取相应数据信息,最终打开运行数据库。 ...
  • oracle时间函数

    千次阅读 2011-11-02 16:57:34
    Oracle时间日期操作 sysdate+(5/24/60/60) 在系统时间基础上延迟5秒 sysdate+5/24/60 在系统时间基础上延迟5分钟 sysdate+5/24 在系统时间基础上延迟5小时 sysdate+5 在系统时间基础上延迟5天 add_months...
  • Oracle 进程结构

    千次阅读 2015-06-26 16:51:16
    Oracle 进程结构
  • Oracle 错误总结及问题解决 ORA

    万次阅读 多人点赞 2012-07-08 22:28:45
    ORA-00218: 控制文件的块大小 与 DB_BLOCK_SIZE () 不匹配 ORA-00219: 要求的控制文件大小 超出了允许的最大值 ORA-00220: 第一个例程未安装控制文件,有关详情,请检查警告日志 ORA-00221: 写入控制文件出错 ...
  • 一. 进程概述先来看一下...下载地址:Oracle 11g 架构图 from Oracle University进程是操作系统中的一种机制,它可执行一系列的操作步。在有些操作系统中使用作业(JOB)或任务(TASK)的术语。一个进程通常有它自己...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,710
精华内容 8,284
关键字:

oracle延迟写入