首先最好下载spatialite_gui这个工具,不过外国人的网站也奇怪,要下载到exe工具还得在网站上好好找一番。
https://www.gaia-gis.it/fossil/spatialite_gui/index
进入正题
一、空间索引的概念
对于可以用于移动设备,当然也可以用于pc的sqlite扩展,spatialite。
有一个比较重要的概念就是空间索引了。
假设我们建好的表是testTable,主键为testTableId,可以增加图形列
SELECT AddGeometryColumn('testTable', 'GeometryColum',4326, 'POLYGON', 'XY')
然后我们可以执行
SELECT CreateSpatialIndex('testTable', 'GeometryColum')
就建立了空间索引。 关于这种索引的详细说明,可以查看官网
http://www.gaia-gis.it/gaia-sins/index.html
以及
http://www.gaia-gis.it/gaia-sins/spatialite-cookbook/html/rtree.html
当然官网很多术语等。看完了专业术语。至于这个叫做Rtree的索引怎么用。还得自己研究啊。
CreateSpatialIndex语句会创建空间索引表,如果我们用spatialite_gui.exe这个工具就可以打开查询索引表。
索引表的命名规则是idx_Tablename_GeometryColumnName, 索引表一般放在Spatial Index类下。
打开查看可以看到如下结构。每个表建的索引都是一样结构。 pkid就是对于数据表的主键值。
就是说这个RTree 索引的核心其实是把每个图形的范围记录在了索引表中。 范围就是后面的4个数字。
二、空间索引的使用
如何使用RTree是一个即简单又复杂的问题。
1、例子
最简单的使用如下:
select * from testTable where ST_Within( MakePoint(106.1,25.6,4326) ,GeometryColum) and testTableId
in (select pkid from idx_testTable_GeometryColum where xmin>106.1-0.003 and ymin>25.6-0.003 and xmax<106.1+0.003 and ymax <25.6+0.003)
2、解释
使用以上sql语句查询testTable就是一种最基本的对空间索引的使用。
其中:MakePoint是spatialite的函数就是按照x,y,srid(4326是wgs 经纬坐标的id).
testTable是表名
GeometryColum是图形列名
testTableId是测试表主键
pkid是索引表主键,和testTableId对应的
idx_testTable_GeometryColum是索引表名
xmin>106.1-0.003 and ymin>25.6-0.003 and xmax<106.1+0.003 and ymax <25.6+0.003, 这个条件构造了一个范围条件,就是以查询点为中心长宽0.006的矩形范围。
以上语句查询的执行过程其实就是现在按照范围数字在索引表查到了范围0.006度内的记录,然后再将符合的记录和查询点(106.1,25.6)进行ST_Within进行空间包含判断。
最终返回包含该点的记录。
3、原理
spatialite是首先执行属性条件过滤然后再进行空间查询的。也就是说即使该testTable表有大量数据,但是我们根据索引表范围限制,永远在指定的范围内查有限的记录。
测试一下可以发现,使用了索引速度一般能提高20至100倍的空间图形查询速度。测试方法也可以不用编程直接使用spatialite_gui.exe这个工具即可。 没有关联idx_testTable_GeometryColum条件就是一般查询。
三、更加复杂的设计
以上我们只是指定了一个固定的范围就是0.003*2度,但是实际上这个范围没有什么科学性。
实际使用中怎么办呢。个人认为有两种办法。
1、一种是针对自己数据可以使用的最大索引范围
就是select max(xmax-xmin) from idx_testTable_GeometryColum
select max(ymax-ymin) from idx_testTable_GeometryColum
得到自己用的表的记录中最大范围作为索引查询的范围
2、是针对自己使用的数据的最优范围
确定最优范围的根本问题就是即保障执行效率,又保障数据准确。
简单来说最小的查询范围速度最快,但是范围越小。可能查到的数据被过滤掉很多。有可能查不到或者查不全。
目前来看如果要最优的使用索引,第一要分析数据,第二还要结合编程实现。