ArcSDE vs. Oracle Spatial 11

1. 格网索引的创建和调整

ArcSDE提供了最多3级的空间索引,如何选择空间索引的层级、格网的网格大小设置多少合适等都关系到空间数据的性能。这里我们通过一个简单的Polygon图层入手,探讨一些格网空间索引的性能影响因素。

首先我们在ArcSDE中准备一个WGS84的面层,名为“TESTGRID”。在这个面层上我们添加2个要素,一个较小,一个较大,如图 10所示。为了提供一些参考信息,图中还将WGS84坐标范围按照30度的尺寸进行了分割,显示在这2个要素之下。

image

图 10 ArcSDE中有2个要素的面层

上述的数据如果我们创建3级索引,为了直观起见,我们可以把最小的网格尺寸定位30,也就是图 10中方格的大小。因此网格最大的第3级可以选择尺寸为270×270,那么第2级可以设置为90×90,第1级设置为30×30。我们如下创建空间索引:

SQL> CREATE INDEX A141_IX1 on TESTGRID(shape)

INDEXTYPE is ST_SPATIAL_INDEX

PARAMETERS ('ST_GRIDS=30,90,270 ST_SRID=2');

odciindexcreate

CREATE TABLE SDE.S141_IDX$ (gx integer, gy integer, minx integer,miny integer, maxx integer, maxy integer, sp_id

rowid,constraint S141$_IX1 primary key(gx,gy,maxx,maxy,minx,miny,sp_id)) organization index pctthreshold 5 pctfree 0

initrans 4

索引已创建。

让我们看看这个数据集中的2个要素是如何被索引的:

SQL> select * from S141_IDX$;

GX GY MINX MINY MAXX MAXY SP_ID

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

33554432 33554433 2.3376E+11 3.3580E+11 3.8784E+11 4.8211E+11 AAATb9AAFAAAEJIAAA

33554433 33554433 2.3376E+11 3.3580E+11 3.8784E+11 4.8211E+11 AAATb9AAFAAAEJIAAA

15 14 4.6386E+11 4.3176E+11 4.7062E+11 4.3886E+11 AAATb9AAFAAAEJIAAB

SQL> select * from testgrid where rowid='AAATb9AAFAAAEJIAAA';

OBJECTID

----------

SHAPE(ENTITY, NUMPTS, MINX, MINY, MAXX, MAXY, MINZ, MAXZ, MINM, MAXM, AREA, LEN, SRID, POINTS)

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

1

ST_GEOMETRY(8, 8, -166.23891, -64.197952, -12.163823, 82.105802, NULL, NULL, NULL, NULL, 12078.8885, 439.10602, 2, 'A001

000001000000BEE79CA1B50FB1D3C6A0C819C89FA3CDE701DA85E8C8E2019FEDA487A902F8E9B481920185D4FDCDB002F9EFC4E08D03A8A697A4A204

99F1A8D8CC03E683F0859701BDBDB2CFC203C4BDF6ED9C0384D1B5DEB201DA88B0B8E002CFA1AFDBBF02')

SQL> select * from testgrid where rowid='AAATb9AAFAAAEJIAAB';

OBJECTID

----------

SHAPE(ENTITY, NUMPTS, MINX, MINY, MAXX, MAXY, MINZ, MAXZ, MINM, MAXM, AREA, LEN, SRID, POINTS)

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

2

ST_GEOMETRY(8, 4, 63.8600683, 31.7610922, 70.6177474, 38.8566553, NULL, NULL, NULL, NULL, 22.6047828, 21.6768769, 2, '2A

00000001000000B0BF87B0B21BBA86A9DEC519CD81D0AC32F8E6EC9114A89AF7E52ACCE780DD20A5E6D8C60784CEEDEE34')

从节点数目可以判断,'AAATb9AAFAAAEJIAAA'对应的是大的多边形,'AAATb9AAFAAAEJIAAB'对应的是小的多边形。先看小的多边形,GX、GY分别为15、14,可见小多边形是在网格尺寸为30的第1级上被索引的;而大多边形被索引了2次,应该是在其它级别上被索引的,但是GX、GY的值却不能用前面的简单的算法来解释,这是为什么呢?

事实上,这个大的多边形是在第3级上进行的索引,也就是说ArcSDE自己会判断一个几何对象到底应该在第几级上进行索引,关于这个算法,可以从ArcSDE的SPX_UTIL包里找到:

Procedure compute_feat_grid_envp (gsize1 IN integer,

gsize2 IN integer,

gsize3 IN integer,

e_minx IN integer,

e_miny IN integer,

e_maxx IN integer,

e_maxy IN integer,

g_minx Out integer,

g_miny Out integer,

g_maxx Out integer,

g_maxy Out integer)

IS

Begin

g_minx := trunc(e_minx / gsize1);

g_miny := trunc(e_miny / gsize1);

g_maxx := trunc(e_maxx / gsize1);

g_maxy := trunc(e_maxy / gsize1);

If ((g_maxx - g_minx + 1) * (g_maxy - g_miny + 1) > max_grids_per_level

AND gsize2 > 0) THEN

g_minx := trunc(e_minx / gsize2);

g_miny := trunc(e_miny / gsize2);

g_maxx := trunc(e_maxx / gsize2);

g_maxy := trunc(e_maxy / gsize2);

If ((g_maxx - g_minx + 1) * (g_maxy - g_miny + 1) > max_grids_per_level

AND gsize3 > 0) THEN

g_minx := trunc(e_minx / gsize3);

g_miny := trunc(e_miny / gsize3);

g_maxx := trunc(e_maxx / gsize3);

g_maxy := trunc(e_maxy / gsize3);

g_minx := g_minx + grid_level_mask_2;

g_miny := g_miny + grid_level_mask_2;

g_maxx := g_maxx + grid_level_mask_2;

g_maxy := g_maxy + grid_level_mask_2;

ELSE

g_minx := g_minx + grid_level_mask_1;

g_miny := g_miny + grid_level_mask_1;

g_maxx := g_maxx + grid_level_mask_1;

g_maxy := g_maxy + grid_level_mask_1;

End If;

End If;

End compute_feat_grid_envp;

其中有几个常量,在SPX_UTIL的包头里可以找到:

max_grids_per_level Constant pls_integer := 4;

grid_level_mask_1 Constant pls_integer := 16777216;

grid_level_mask_2 Constant pls_integer := 33554432;

也就是说ArcSDE索引一个几何对象的时候是从第1级格网开始判断,如果某个几何对象跨越的网格数大于1个(或者说1个网格不能包含某个几何对象)、同时第2级的网格尺寸大于0的时候, ArcSDE就会在第2级网格上再进行类似的计算;同理,如果还有第3级网格可用,ArcSDE还有可能把该几何对象索引到第3级网格上去。总的来说,ArcSDE试图用最少的网格来索引几何对象。

另外,为了区分不同级别的网格,这里还有grid_level_mask_1=16777216和grid_level_mask_2=33554432两个常量,分别用于第2级和第3级网格序号的标识,不同级别的网格会根据当前格网的等级分别加上0(第1级)或grid_level_mask_1(第2级)或grid_level_mask_2(第3级)。由此可见,上面那个大的多边形被索引的两个网格的GX、GY应该减去33554432,也就是分别是GX=0,GY=1和GX=1,GY=1,这是个第3级的索引。

基于上面的原则,我们可以对如何选取空间索引的网格尺寸应该有一些原则性的判断:

l 如果没有特别的需要,可以使用一级索引的话用一级索引会比较好,因为如果有多级索引,查询的时候会扫描所有的索引级别

l 对于几何对象大小变化较大,并且各个量级的对象数量相当的数据才可能需要设置多级索引

l 对于点数据,只需要设置一级索引(几何对象大小没有变化),并且设置网格到较大的尺寸(避免一个网格中只有几个点的情况)

l 如果数据量有了很大的变化以后,可能需要重新计算并调整网格的尺寸

对于网格的尺寸,可以通过数据的范围平均值进行一个估算,一般可以取该值的3~4倍,比如对于刚才的那个面层,通过这样的命令可以进行一个大概的估算:

SQL> select 4*( avg(t.shape.maxx-t.shape.minx) + avg(t.shape.maxy-t.shape.maxy) )/2 from testgrid t;

4*(AVG(T.SHAPE.MAXX-T.SHAPE.MINX)+AVG(T.SHAPE.MAXY-T.SHAPE.MAXY))/2

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

160.832765

当然,更简单的方法就是通过ArcCatalog来计算,如图 11。

image

图 11 通过ArcCatalog来重新计算适合的网格尺寸

 

你可能感兴趣的:(oracle,sql,null,Integer,Parameters,网格)