在新建图层或导入图层时,ArcSDE 自动建立Grid Index,该索引已基于图层的spatial
reference、图形类型等信息进行了优化,而且默认情况下只建立一级索引,Grid Index 存储
于S 表中。
ArcSDE 提供最多三级索引,第一级索引的Cell Size 最小,第三级最大,Grid Index
必须逐级建立,不可跨越建Grid Index,一般情况下建立一级索引即可满足多数情况下的
性能需求。
Grid Index 中Cell Size 决定了Grid Index 性能优劣,如果图层中单个图形覆盖范围差
异很大,而且该图层数据量较大(如超过10 万条记录),可以考虑建立多级索引。建立Grid
Index 可以参考以下原则:
1. 点层只需建立单级索引,而且Grid Cell Size 可以选择得大一些,因为点层处理效率是最高的;
2. 监视spatial index,如果数据变化频繁,则需要经常根据数据的变化情况重新评估索引的优劣;
3. 根据实际应用,将Grid Index 中Cell Size 调整为应用程序经常使用的窗口显示大小;
4. 对于未知应用,可以将Grid Index 中Cell Size 设置为图形平均覆盖范围的三倍大小;
图形平均覆盖范围的计算方法:
select (avg(emaxx - eminx) + avg(emaxy - eminy)) / 2 from f<N> ;
图层各种统计信息查询方法:
sdelayer -o stats -l layer_name,spatial_column_name –u sde_user_name -p sde_user_password –I
service_name;
这些信息是确定Grid Index 中Cell Size 大小的重要依据。
图形统计信息查询方法:
sdelayer -o si_stats -l layer_name,spatial_column_name –u sde_user_name -p sde_user_password –I
service_name;
Grid Index 调整方法(注册版本后不可调整):
1. 通过Catalog 实现:
选中图层的Spatial 字段(默认情况下是shape 字段),修改起Grid Index 参数;
2. 通过SDE 命令行实现:
Sdelayer –o alter –l layer_name,spatial_column_name –g grid_size0,grid_size1,grid_size2 –u
sde_user_name -p sde_user_password –I service_name;
试验中,发现对于一般的图层,图层建立时设定的默认Cell Size 已经比较优化,
根据图层的实际信息优化Cell Size 后并未获得性能上的明显提升。
对于mdb是放在GDB_GeomColumns中可以自己手工修改
具体可以找esri的例子,里面有个
'======================================
Function DefaultIndexGridPoint(InFC As IFeatureClass) As Double
' Calculates the Index grid based on input feature class
' Get the dataset
Dim pGeoDataSet As IGeoDataset
Set pGeoDataSet = InFC
' Get the envelope of the input dataset
Dim pEnvelope As IEnvelope
Set pEnvelope = pGeoDataSet.Extent
'Calculate approximate first grid
Dim lngNumFeat As Long
Dim dblArea As Double
lngNumFeat = InFC.FeatureCount(Nothing)
If lngNumFeat = 0 Or pEnvelope.IsEmpty Then
' when there are no features or an empty bnd - return 1000
DefaultIndexGridPoint = 1000
Else
dblArea = pEnvelope.Height * pEnvelope.Width
' approximate grid size is the square root of area over the number of features
DefaultIndexGridPoint = Sqr(dblArea / lngNumFeat)
End If
Set pGeoDataSet = Nothing
Set pEnvelope = Nothing
End Function
Function DefaultIndexGrid(InFC As IFeatureClass) As Double
' Calculate approximate first grid
' based on the average of a random sample of feature extents times five
Dim lngNumFeat As Long
Dim lngSampleSize As Long
Dim pFields As IFields
Dim pField As IField
Dim strFIDName As String
Dim strWhereClause As String
Dim lngCurrFID As Long
Dim pFeat As IFeature
Dim pFeatCursor As IFeatureCursor
Dim pFeatEnv As IEnvelope
Dim pQueryFilter As IQueryFilter
Dim pNewCol As New Collection
Dim lngKMax As Long
Dim dblMaxDelta As Double
dblMaxDelta = 0
Dim dblMinDelta As Double
dblMinDelta = 1000000000000#
Dim dblSquareness As Double
dblSquareness = 1
Dim i As Long
Dim j As Long
Dim k As Long
Const SampleSize = 1
Const Factor = 1
' Create a recordset
Dim ColInfo(0), c0(3)
c0(0) = "minext"
c0(1) = CInt(5)
c0(2) = CInt(-1)
c0(3) = False
ColInfo(0) = c0
'ADC1.SourceRecordset = ADF1.CreateRecordSet(ColInfo)
lngNumFeat = InFC.FeatureCount(Nothing) - 1
If lngNumFeat <= 0 Then
DefaultIndexGrid = 1000
Exit Function
End If
'if the feature type is points use the density function
If InFC.ShapeType = esriGeometryMultipoint Or InFC.ShapeType = esriGeometryPoint Then
DefaultIndexGrid = DefaultIndexGridPoint(InFC)
Exit Function
End If
' Get the sample size
lngSampleSize = lngNumFeat * SampleSize
' Don't allow too large a sample size to speed
If lngSampleSize > 1000 Then lngSampleSize = 1000
' Get the ObjectID Fieldname of the feature class
Set pFields = InFC.Fields
' FID is always the first field
Set pField = pFields.Field(0)
strFIDName = pField.Name
' Add every nth feature to the collection of FIDs
For i = 1 To lngNumFeat Step CLng(lngNumFeat / lngSampleSize)
pNewCol.Add i
Next i
For j = 0 To pNewCol.Count - 1 Step 250
' Will we top out the features before the next 250 chunk?
lngKMax = Min(pNewCol.Count - j, 250)
strWhereClause = strFIDName + " IN("
For k = 1 To lngKMax
strWhereClause = strWhereClause + CStr(pNewCol.Item(j + k)) + ","
Next k
' Remove last comma and add close parenthesis
strWhereClause = Mid(strWhereClause, 1, Len(strWhereClause) - 1) + ")"
Set pQueryFilter = New QueryFilter
pQueryFilter.WhereClause = strWhereClause
If Not (m_pSpatialReference Is Nothing) Then
Set pQueryFilter.OutputSpatialReference(InFC.ShapeFieldName) = m_pSpatialReference
End If
Set pFeatCursor = InFC.Search(pQueryFilter, True)
Set pFeat = pFeatCursor.NextFeature
While Not pFeat Is Nothing
' Get the extent of the current feature
Set pFeatEnv = pFeat.Extent
' Find the min, max side of all extents. The "Squareness", a measure
' of how close the extent is to a square, is accumulated for later
' average calculation.
dblMaxDelta = Max(dblMaxDelta, Max(pFeatEnv.Width, pFeatEnv.Height))
dblMinDelta = Min(dblMinDelta, Min(pFeatEnv.Width, pFeatEnv.Height))
If dblMinDelta <> 0 Then
dblSquareness = dblSquareness + ((Min(pFeatEnv.Width, pFeatEnv.Height) / (Max(pFeatEnv.Width, pFeatEnv.Height))))
Else
dblSquareness = dblSquareness + 0.0001
End If
Set pFeat = pFeatCursor.NextFeature
Wend
Next j
' If the average envelope approximates a square set the grid size half
' way between the min and max sides. If the envelope is more rectangular,
' then set the grid size to half of the max.
If ((dblSquareness / lngSampleSize) > 0.5) Then
DefaultIndexGrid = (dblMinDelta + ((dblMaxDelta - dblMinDelta) / 2)) * Factor
Else
DefaultIndexGrid = (dblMaxDelta / 2) * Factor
End If
End Function
'======================================
其中DefaultIndexGrid函数就是计算要素类的 gridsize.