link:
http://blog.csdn.net/linghe301/article/details/20900615

2014-03-14 09:20 2686人阅读 评论(6) 收藏 举报

 分类:

 
 

)  ArcGIS Engine(30)  ST_Geometry(30)  Oracle(106)  性能优化(53) 

版权声明:本文为博主原创文章,未经博主允许不得转载。

目录(?)[+]

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

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

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

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

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

代码因素

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

 

                                                       ArcGIS Engine                                                    

年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支持多线程,但是不支持多个线程之间的彼此调用。

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

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

  1. public class VersionEditing  
  2.    {  
  3.        /// <summary>  
  4.        /// 更新要素类指定字段值  
  5.        /// </summary>  
  6.        /// <param name="parameter">要素类名称</param>  
  7.        public void UpdateFiledValue(object parameter)  
  8.        {  
  9.     ........  
  10.        }  
  11.      }  

    编写多线程函数,调用这个更新要素类的函数

  12. private void MultiThreadEditing()  
  13.         {  
  14.             VersionEditing VersionEditing = new GIS.VersionEditing();  
  15.             //声明线程对象  
  16.             Thread thA = new Thread(new ParameterizedThreadStart(VersionEditing.UpdateFiledValue));  
  17.             Thread thB = new Thread(new ParameterizedThreadStart(VersionEditing.UpdateFiledValue));  
  18.             //设置线程工作模型  
  19.             thA.SetApartmentState(ApartmentState.STA);  
  20.             thB.SetApartmentState(ApartmentState.STA);  
  21.             //启动线程  
  22.             thA.Start("featureclass1");  
  23.             thA.Start("featureclass2");  
  24.         }  

     

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

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

  25. //建议的方法  
  26. public static void InsertFeaturesUsingCursor(IFeatureClass featureClass, List <  
  27.     IGeometry > geometryList)  
  28. {  
  29.     using(ComReleaser comReleaser = new ComReleaser())  
  30.     {  
  31.         // Create a feature buffer.  
  32.         IFeatureBuffer featureBuffer = featureClass.CreateFeatureBuffer();  
  33.         comReleaser.ManageLifetime(featureBuffer);  
  34.   
     
  35.         // Create an insert cursor.  
  36.         IFeatureCursor insertCursor = featureClass.Insert(true);  
  37.         comReleaser.ManageLifetime(insertCursor);  
  38.   
     
  39.         // All of the features to be created are classified as Primary Highways.  
  40.         int typeFieldIndex = featureClass.FindField("TYPE");  
  41.         featureBuffer.set_Value(typeFieldIndex, "Primary Highway");  
  42.         foreach (IGeometry geometry in geometryList)  
  43.         {  
  44.             // Set the feature buffer's shape and insert it.  
  45.             featureBuffer.Shape = geometry;  
  46.             insertCursor.InsertFeature(featureBuffer);  
  47.         }  
  48.   
     
  49.         // Flush the buffer to the geodatabase.  
  50.         insertCursor.Flush();  
  51.     }  
  52. }  

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

     

    :游标

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

  53. Public Void test()  
  54. {                  
  55.         workspaceEdit.StartEditOperation();  
  56.                 IQueryFilter queryFilter = new QueryFilter();  
  57.                 queryFilter.WhereClause = clause;  
  58.                 //是否重复绑定游标  
  59.                 ICursor updateCursor = table.Update(queryFilter, true);  
  60.                 comReleaser.ManageLifetime(updateCursor);  
  61.                 int fieldIndex = table.Fields.FindField("FWMC");  
  62.                 IRow temp = null;  
  63.                 while ((temp = updateCursor.NextRow()) != null)  
  64.                 {  
  65.                     temp.set_Value(fieldIndex, "aaaa");  
  66.                     updateCursor.UpdateRow(temp);  
  67.                 }  
  68.                 workspaceEdit.StopEditOperation();  
  69. }  

    如果选择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会导致缓存提交到数据库

:资源回收

尽可能使用Esri提供的MangeLifetime来管理ArcGIS Engine对象的生命周期,系统会自动进行维护,而不需要在使用类似以下方式进行释放资源了。(由于版本原因,可能有所不同)

 ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(o);

System.Runtime.InteropServices.Marshal.ReleaseComObject(o);

GC.Collect();

 

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

  1. /// <summary>  
  2.         /// 执行空间缓存  
  3.         /// </summary>  
  4.         /// <param name="pFWS">工作空间</param>  
  5.         /// <param name="pEnv">缓存区域</param>  
  6.         private void SpatialCache(IFeatureWorkspace pFWS, IEnvelope pEnv)  
  7.         {  
  8.             if (m_pWS != null)  
  9.             {  
  10.                 ISpatialCacheManager3 pSCM = m_pWS as ISpatialCacheManager3;  
  11.                 if (!pSCM.CacheIsFull)  
  12.                 {  
  13.                     pSCM.FillCache(pEnv);  
  14.                 }  
  15.   
     
  16.                 //执行空间操作代码  
  17.   
     
  18.                 //清空缓存  
  19.   
     
  20.                 pSCM.EmptyCache();  
  21.                 
     
  22.             }  
  23.         }  

     

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

     

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

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

     

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

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

    IDatasetEdit

     

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

     

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

     

     

                                                  空间SQL  
     
     
     
     
     
     
     
     
                           

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

    :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

 

:尽可能的使用存储过程

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

 

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

 

 

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

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

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

 

:如果进行更新操作,就需要留意索引

用户进行更新,需要先查询出需要更新的要素对象,那么不管是通过属性索引或者空间索引进行查询,都需要这些索引对象有效。

而且在编辑完毕之后,还需要对这些索引对象重新创建,保证新编辑对象的索引更新。

 

:数据库归档日志关闭

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

 

:禁用表空间日志

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

 

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

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

 

 

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

 

操作示例:

 

:禁用归档日志

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;

 

:禁用表空间日志

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;

 

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

 

:启用表空间日志

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;

 

:启用归档日志

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;

 

:版本编辑的状态压缩

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

 

:Oracle参数

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

 

:其他因素

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

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

 

 

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

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

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

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

怎么提高ArcSDE 写入地理数据库的效率的更多相关文章

  1. 提高Order by语句查询效率的两个思路

    提高Order by语句查询效率的两个思路 2011-03-01 13:07 水太深 ITPUB 字号:T | T 在MySQL数据库中,Order by语句的使用频率是比较高的.但是众所周知,在使用 ...

  2. EJB通过ANT提高EJB应用的开发效率、开发具有本地接口的无状态bean、开发有状态bean

    把jboss集成进eclipse 关闭Jboss控制台按Ctrl+c,在MyEclipse→Servers→Jboss里面可以配置JBoss. 通过ANT提高EJB应用的开发效率 在HelloWorl ...

  3. 如何提高使用Java反射的效率?

    前言 在我们平时的工作或者面试中,都会经常遇到“反射”这个知识点,通过“反射”我们可以动态的获取到对象的信息以及灵活的调用对象方法等,但是在使用的同时又伴随着另一种声音的出现,那就是“反射”很慢,要少 ...

  4. 如何提高scrapy的爬取效率

    提高scrapy的爬取效率 增加并发: 默认scrapy开启的并发线程为32个,可以适当进行增加.在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置 ...

  5. 读《实战GUI自动化测试》之:第三步,如何提高测试结果分析的效率

    转自:http://www.ibm.com/developerworks/cn/rational/r-cn-guiautotesting3/ 所谓自动化测试,就是“自动化”+“测试”.自动化本身显然不 ...

  6. java关于StringBuffer和StringBuilder写入文件的效率问题

    StringBuffer在存储字符的时候,是有上限的,一旦达到上线就会出错,自己在项目中遇到一个从数据库中查询数据,然后写入到本地文件中 ,数据量大概有30万条,此时的效率十分的低.下面是大致的模拟该 ...

  7. 关于如何提高Web服务端并发效率的异步编程技术

    最近我研究技术的一个重点是java的多线程开发,在我早期学习java的时候,很多书上把java的多线程开发标榜为简单易用,这个简单易用是以C语言作为参照的,不过我也没有使用过C语言开发过多线程,我只知 ...

  8. 提高你的数据库编程效率:Microsoft CLR Via Sql Server

    你还在为数据库编程而抓狂吗?那些恶心的脚本拼接,低效的脚本调试的日子将会与我们越来越远啦.现在我们能用支持.NET的语言来开发数据库中的对象,如:存储过程,函数,触发器,集合函数已及复杂的类型.看到这 ...

  9. 提高Vector容器的删除效率

    vector容器是类似与一个线性数组,索引效率高,插入,删除的效率很低,需要遍历数据列表,一般情况下vector的删除操作由一下函数完成: iterator erase(iterator positi ...

随机推荐

  1. Backtracking line search的理解

    使用梯度下降方法求解凸优化问题的时候,会遇到一个问题,选择什么样的梯度下降步长才合适. 假设优化函数为,若每次梯度下降的步长都固定,则可能出现左图所示的情况,无法收敛.若每次步长都很小,则下降速度非常 ...

  2. Codeforces Round #160 (Div. 2)

    A. Roma and Lucky Numbers 暴力计算. B. Roma and Changing Signs 每次取最小值改变正负,优先队列维护. C. Maxim and Discounts ...

  3. 在C#中使用C++编写的类

    现在在Windows下的应用程序开发,VS.Net占据了绝大多数的份额.因此很多以前搞VC++开发的人都转向用更强大的VS.Net.在这种情况下,有很多开发人员就面临了如何在C#中使用C++开发好的类 ...

  4. Unity3d 引擎原理详细介绍

    体系结构 为了更好地理解游戏的软件架构和对象模型,它获得更好的外观仅有一名Unity3D的游戏引擎和编辑器是非常有用的,它的主要原则. Unity3D 引擎 Unity3D的是一个屡获殊荣的工具,用于 ...

  5. OrmLite数据库的使用方法

    第一步:导入架包     1.将orm的两个支持包放入project视图下的你的工程的lib目录里(这两个JAR包网上都有,GitHub上最新)     2.添加依赖:在file文件目录下的proje ...

  6. SpringMVC学习系列(10) 之 异常处理

    在项目中如何处理出现的异常,在每个可能出现异常的地方都写代码捕捉异常?这显然是不合理的,当项目越来越大是也是不可维护的.那么如何保证我们处理异常的代码精简且便于维护呢?这就是本篇要讲的内容—>异 ...

  7. LeetCode "Russian Doll Envelopes"

    An intuitive DP - should be 'medium'. class Solution { public: int maxEnvelopes(vector<pair<in ...

  8. java 网络编程复习(转)

    好久没有看过Java网络编程了,现在刚好公司有机会接触,顺便的拾起以前的东西 参照原博客:http://www.cnblogs.com/linzheng/archive/2011/01/23/1942 ...

  9. 随笔 高质量 C++/C 编程指南

    内存分配方式有三种:) 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量, static 变量.) 在栈上创建.在执行函数时,函数内局部变量的存储 ...

  10. 设置ajax 同步执行

    Ajax请求默认的都是异步的如果想同步 async设置为false就可以(默认是true) var html = $.ajax({  url: "some.php",  async ...