如何在Informix中创建并使用函数索引(三)

日期: 2009-03-01 作者:Carla Wilcox 来源:TechTarget中国 英文

示例:使用R-Tree访问方法的函数索引

在本例中,我们将向您展示如何创建使用 R-Tree 访问方法的函数索引。R-Tree数据结构可以保存有关多维数据的信息,并用于有关空间或地理数据的索引。这类索引有助于改善针对空间数据的查询的性能。

要理解本示例,需要熟悉 IDS DataBlade 技术。具体来说,您应该能够安装和配置所使用的 Spatial DataBlade。有关 DataBlade 的详细信息,请参考 IBM Informix Spatial DataBlade 用户指南。

本例使用的数据包括一些城市的地理数据和 Oregon 州的海啸影响范围。本文下载部分没有提供这些地理数据,但是可以通过 Oregon Geospatial Enterprise Office 网站 自由获取。可从该站点下载 City Limits 2007 和 Tsunami Inundation Line 数据集。

假设您希望查找即将受海啸影响的城市。为此,发出一个空间数据查询,搜索其中心包含在海啸线内的所有城市。要满足这个查询,必须计算地理城市中心,因此,需要创建一个函数索引来计算这个值。由于涉及到空间数据,您需要为这个索引指定 R-Tree 访问方法。

下面列出了R-Tree函数索引的一些有趣特性:

它们不仅是针对相交区域的索引;叶页(leaf page)面保存数据对象本身。R-Tree具有高度上的平稳性:

  • 从根页面到任何叶页面的路径均穿过相同数量的层。
  • 所有 leave 节点都位于同一级别。

设置

本例中使用的空间函数来自Spatial DataBlade。因此,创建和使用索引不需要编写额外的代码。

该示例针对运行在 64 位 Linux x86 上的 IDS version 11.10 进行了测试。可针对不同平台对指令进行相应修改。

设置以下环境变量:


INFORMIXDIR     the location of your IDS installation
PATH            add $INFORMIXDIR/bin
                add $INFORMIXDIR/extend/<spatialDataBladeDir>/bin (see below) 


  安装Spatial DataBlade。安装指导可从 IDS 11.10 信息中心获得(参考本文末尾的链接)。

下面的指令假设您已经在默认位置安装好了 Spatial DataBlade version 8.21: $INFORMIXDIR/extend/spatial.8.21.xC1,其中 ‘x’ 表示特定于平台的字母。对于 64 位 Linux x86,默认位置为 $INFORMIXDIR/extend/spatial.8.21.FC1。可根据您的环境对指令作出相应修改。

为空间数据创建 sbspace。注意:sbspace 名必须与 ONCONFIG 文件中的 SYSSBSPACENAME 值匹配。本例假设 sbspace 名为 syssbspace。

在与根dbspace相同的目录中创建名为 syssbspace 的空文件(ONCONFIG 文件中 ROOTPATH 的值指定根dbspace的名称和位置)。

将文件所有权改为informix:informix。
将文件权限改为mode 660。

以用户informix的身份,创建sbspace:


onspaces -c -S syssbspace -p <fullpath>/syssbspace -o 0 -s 100000 

  创建您的数据库。


dbaccess – –
create database spatialdb; 

  注册 Spatial DataBlade。

使用 blademgr 实用工具注册 Spatial DataBlade。Spatial DataBlade 依赖于 R-Tree DataBlade,后者由 IDS 自动附带。因此,必须同时向您的数据库注册这两个 DataBlade。


blademgr
register ifxrltree.2.00 spatialdb
register spatial.8.21.FC1 spatialdb
list spatialdb
    DataBlade modules registered in database spatialdb:
        ifxrltree.2.00        spatial.8.21.FC1 

  加载空间数据。

从City Limits 2007和Tsunami Inundation Line下载中提取文件,并分别保存在两个目录中,即citylim_2007和tsunami:                 


       ls citylim_2007
citylim_2007.dbf
citylim_2007.prj
citylim_2007.sbn
citylim_2007.sbx
citylim_2007.shp
citylim_2007.shp.xml
citylim_2007.shx
ls tsunami
PRJdevelopment.pdf
tsunami.dbf 
tsunami.html
tsunami.pdf
tsunami.prj
tsunami.shp
tsunami.shp.xml
tsunami.shx 

注意:在 UNIX 上,数据文件名称区分大小写,而且必须为小写。这是 Shapefile 数据的要求。如果文件名不正确,那么 loadshp 实用工具将报告错误,指出它无法找到数据文件。

关于如何正确配置投影数据超出本文讨论的范围。如果没有正确配置,loadshp 实用工具在尝试处理投影信息时将返回错误,因此,隐藏或删除扩展名为 ‘prj’ 的文件:


rm citylim_2007/citylim_2007.prj
rm tsunami/tsunami.prj 

  使用Spatial DataBlade附带的loadshp实用工具将数据加载到 IDS 中。该实用工具位于 $INFORMIXDIR/extend/spatial.8.21.FC1/bin 中。 loadshp 创建了两个表:cities 和 tsunami,并将空间数据分别加载到 citylim 和 inundation 列中。


$INFORMIXDIDR/extend/spatial.8.21.FC1/bin/loadshp -o create -D spatialdb2 
    -l cities,citylim -f <fullpath>/citylim_2007
$INFORMIXDIDR/extend/spatial.8.21.FC1/bin/loadshp -o create -D spatialdb2 
    -l tsunami,inundation -f <fullpath>/tsunami 


  查询

发出查询。在这个查询中,

st_intersects、st_centroid 和 st_envelope 由 Spatial DataBlade 提供
st_envelope 计算每条海啸线的边界,返回类型 st_multilinestring
st_centroid 计算每个城市的中心,返回类型 st_multipolygon
st_intersects 可确定两种结构是否相互交叉
这次没有定义函数索引。  


  dbaccess spatialdb –
    set explain on;
    select city_name from cities, tsunami
    where st_intersects( st_centroid( citylim ), st_envelope( inundation ) );
    city_name                      
    Astoria                       
    Bandon                        
    Bay City                      
    Brookings                     
    Cannon Beach                  
    Cave Junction                 
    Coos Bay                      
    Coquille                      
    Depoe Bay                     
    Dunes City                    
    Elkton                        
    Falls City                    
    Florence                      
    Garibaldi                     
    Gearhart                      
    Glendale                      
    Gold Beach                    
    Grants Pass                   
    Lakeside                      
    Lincoln City                  
    Manzanita                     
    Myrtle Point                  
    Nehalem                       
    Newport                       
    North Bend                    
    Port Orford                   
    Powers                        
    Reedsport                     
    Riddle                        
    Rockaway Beach                
    Seaside                       
    Siletz                        
    Tillamook                     
    Toledo                        
    Waldport                      
    Warrenton                     
    Wheeler                       
    Willamina                     
    Winston                       
    Yachats                       
    40 row(s) retrieved. 


  检查SQL EXPLAIN 输出。该查询计划显示了全表扫描。针对每一个元组(tuple)执行 st_centroid() 计算。


QUERY:
——
select city_name from cities, tsunami
where st_intersects( st_centroid( citylim ), st_envelope( inundation ) )
Estimated Cost: 25671
Estimated # of Rows Returned: 7018
  1) <owner>.tsunami: SEQUENTIAL SCAN    <== Full Table Scan
  2) <owner>.cities: SEQUENTIAL SCAN     <== Full Table Scan
        Filters: informix.st_intersects(informix.st_centroid(<owner>.cities.citylim ),
|–10——–20——–30——–40——–50——–60——–70——–80——–9|
|——– XML error:  The previous line is longer than the max of 90 characters ———|
                 informix.st_envelope(<owner>.tsunami.inundation ))
NESTED LOOP JOIN
UDRs in query:
————–
    UDR id  :   662
    UDR name:   st_intersects
    UDR id  :   626
    UDR name:   st_envelope
    UDR id  :   567
    UDR name:   st_centroid 


  创建函数索引计算城市中心。 


dbaccess spatialdb –
   create index citycenterindex
   on cities( st_centroid( citylim ) st_geometry_ops )
   using rtree; 


有关这个索引,需注意以下几点:

指定 R-Tree 访问方法。
st_centroid() 计算城市中心。
st_geometry_ops 指定操作符类。
将操作符类与访问方法结合使用,可以指定创建索引和优化查询时使用的操作符。操作符类通常为一组函数。对于 Spatial DataBlade,st_geometry_ops 类由以下函数组成:


ST_Contains()
ST_Crosses()
ST_Equals()
SE_EnvelopesIntersect()
ST_Intersects()
SE_Nearest()
SE_NearestBbox()
ST_Overlaps()
ST_Touches()
ST_Within() 

执行相同的查询。


dbaccess spatialdb –
select city_name from cities, tsunami
where st_intersects( st_centroid( citylim ), st_envelope( inundation ) ); 


  注意:当索引表达式被用于关系表达式,或作为某个操作符类函数的参数时,查询优化器将考虑使用函数索引。由于 st_centroid() 是索引 st_geometry_ops 中指定的操作符类的成员,优化器在生成查询计划时将考虑使用索引。

注意:优化器不会对下面这个查询使用函数索引。这是因为 st_distance() 不属于 st_geometry_ops() 操作符类。


select city_name from cities, tsunami
where st_distance( st_centroid( citylim ), inundation ) < 5280; 

  检查 SQL EXPLAIN 输出。该查询计划显示索引扫描使用了函数索引。

注意:查询优化器只有在表统计信息保持最新的情况下使用 R-Tree 索引。这意味着您应该在创建索引之前加载数据,或者在加载数据之后更新表的统计信息。


QUERY:
——
select city_name from cities, tsunami
where st_intersects( st_centroid( citylim ), st_envelope( inundation ) )
Estimated Cost: 12920
Estimated # of Rows Returned: 7018
  1) <owner>.tsunami: SEQUENTIAL SCAN
  2) <owner>.cities: INDEX PATH    <== Index Scan
    (1) VII Index Keys: informix.st_centroid(citylim)   (Serial, fragments: ALL)
        VII Index Filter:
            informix.st_intersects(informix.st_centroid(<owner>.cities.citylim),
            informix.st_envelope(<owner>.tsunami.inundation ))
NESTED LOOP JOIN
UDRs in query:
————–
    UDR id  :   662
    UDR name:   st_intersects
    UDR id  :   626
    UDR name:   st_envelope
    UDR id  :   567
    UDR name:   st_centroid
    UDR id  :   567
    UDR name:   st_centroid 

  结束语

函数索引是一种强大的性能调优工具。通过减少执行查询时需要检索的元组(tuple)的数量,以及减少查询所需的计算,函数索引能够显着改善性能。

除大型对象外,函数索引可以返回任何标准SQL类型。同样,函数索引还可以返回用户定义的类型。函数索引可以指定各种不同的访问方法,包括 B-Tree、R-Tree 和用户定义的访问方法。

函数索引的存储和维护成本较高。您应该对系统进行成本收益分析,并只在能保证获益的情况下创建函数索引。如果数据大小较小,或者索引对于数据库查询的性能改善帮助不大,则不适合使用函数索引。

本文提供了一些有关函数索引的示例。希望我们介绍的这些创建和使用函数索引的方法能够帮助您改善查询搜索的性能。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

相关推荐