通过搜索优化加速地理空间查询¶
搜索优化服务可以通过将地理空间函数与 GEOGRAPHY 对象结合使用的谓词来提高查询的性能。
备注
必须使用 ON 子句为特定列启用此功能,该子句位于 ALTER TABLE ...ADD SEARCH OPTIMIZATION 命令中。例如:
ALTER TABLE mytable ADD SEARCH OPTIMIZATION ON GEO(mygeocol);
如果省略 ON 子句,使用地理空间函数的查询不会得到改进。
以下部分提供了更多详细信息:
备注
尚不支持 GEOMETRY 对象。
使用地理空间函数的谓词¶
对于带有使用以下函数的谓词的查询:
在以下情况下,搜索优化服务可以提高性能:
一个输入表达式是 GEOGRAPHY 表中的列,而且
另一个输入表达式是 GEOGRAPHY 常量(通过 转换或构造函数 创建)。
对于 ST_DWITHIN,距离实参是一个非负值的 REAL 常量。
请注意,此功能具有相同的 适用于搜索优化服务的限制。
其他性能考虑因素¶
由于搜索优化服务主要用于筛选高度针对性的谓词,而且谓词是根据地理空间对象之间的邻近程度进行筛选,因此,在表中根据地理空间对象间的邻近程度对其进行聚类,可以带来更好的性能表现。您可以通过在加载数据时指定排序顺序或使用自动群集来对数据进行聚类,具体取决于基表是否频繁更改:
- 加载预先排序的数据
如果基表中的数据不经常更改,则可以在加载数据时指定排序顺序。然后,您可以对 GEOGRAPHY 列启用搜索优化。例如:
CREATE TABLE new_table AS SELECT * FROM source_table ORDER BY st_geohash(geom); ALTER TABLE new_table ADD SEARCH OPTIMIZATION ON GEO(geom);
每次对基础数据进行重大更改后,您可以手动对数据重新排序。
自动聚类¶
如果您的基表经常更新,您可以使用 ALTER TABLE ...CLUSTER BY ... 命令启用 自动聚类,以便在表发生变更时自动重聚类。
以下示例添加一个 VARCHAR 类型的新列 geom_geohash
,并将GEOGRAPHY 列 geom
的地理哈希或 H3 索引存储在这个新列中。然后,它将新列用作集群键启用自动聚类。这种方法将自动对表中更改的部分进行重聚类。
CREATE TABLE new_table AS SELECT *, ST_GEOHASH(geom) AS geom_geohash FROM source_table;
ALTER TABLE new_table CLUSTER BY (geom_geohash);
ALTER TABLE new_table ADD SEARCH OPTIMIZATION ON GEO(geom);
使用地理空间函数的示例¶
以下语句创建并配置本节示例中使用的表。最后一条语句使用 ON 子句(位于 ALTER TABLE ...ADD SEARCH OPTIMIZATION 命令中)来为 g1
GEOGRAPHY 列添加搜索优化。
CREATE OR REPLACE TABLE geospatial_table (id NUMBER, g1 GEOGRAPHY);
INSERT INTO geospatial_table VALUES
(1, 'POINT(-122.35 37.55)'),
(2, 'LINESTRING(-124.20 42.00, -120.01 41.99)'),
(3, 'POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))');
ALTER TABLE geospatial_table ADD SEARCH OPTIMIZATION ON GEO(g1);
支持的谓词示例¶
以下查询是搜索优化服务支持的查询示例。搜索优化服务可以使用搜索访问路径来提高以下查询的性能:
SELECT id FROM geospatial_table WHERE
ST_INTERSECTS(
g1,
TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'));
以下示例展示了搜索优化服务支持的其他谓词:
...
ST_INTERSECTS(
TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
g1)
...
ST_CONTAINS(
TO_GEOGRAPHY('POLYGON((-74.17 40.64, -74.1796875 40.58, -74.09 40.58, -74.09 40.64, -74.17 40.64))'),
g1)
...
ST_CONTAINS(
g1,
TO_GEOGRAPHY('MULTIPOINT((0 0), (1 1))'))
...
ST_WITHIN(
TO_GEOGRAPHY('{"type" : "MultiPoint","coordinates" : [[-122.30, 37.55], [-122.20, 47.61]]}'),
g1)
...
ST_WITHIN(
g1,
TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'))
...
ST_COVERS(
TO_GEOGRAPHY('POLYGON((-1 -1, -1 4, 4 4, 4 -1, -1 -1))'),
g1)
...
ST_COVERS(
g1,
TO_GEOGRAPHY('POINT(0 0)'))
...
ST_COVEREDBY(
TO_GEOGRAPHY('POLYGON((1 1, 2 1, 2 2, 1 2, 1 1))'),
g1)
...
ST_COVEREDBY(
g1,
TO_GEOGRAPHY('POINT(-122.35 37.55)'))
...
ST_DWITHIN(
TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
g1,
100000)
...
ST_DWITHIN(
g1,
TO_GEOGRAPHY('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
100000)
构建 GEOGRAPHY 常量示例¶
以下谓词示例为构建 GEOGRAPHY 常量使用了不同的 转换和构造函数。
...
ST_INTERSECTS(
g1,
ST_GEOGRAPHYFROMWKT('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'))
...
ST_INTERSECTS(
ST_GEOGFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
g1)
...
ST_CONTAINS(
ST_GEOGRAPHYFROMEWKT('POLYGON((-74.17 40.64, -74.1796875 40.58, -74.09 40.58, -74.09 40.64, -74.17 40.64))'),
g1)
...
ST_WITHIN(
ST_GEOGRAPHYFROMWKB('01010000006666666666965EC06666666666C64240'),
g1)
...
ST_COVERS(
g1,
ST_MAKEPOINT(0.2, 0.8))
...
ST_INTERSECTS(
g1,
ST_MAKELINE(
TO_GEOGRAPHY('MULTIPOINT((0 0), (1 1))'),
TO_GEOGRAPHY('POINT(0.8 0.2)')))
...
ST_INTERSECTS(
ST_POLYGON(
TO_GEOGRAPHY('SRID=4326;LINESTRING(0.0 0.0, 1.0 0.0, 1.0 2.0, 0.0 2.0, 0.0 0.0)')),
g1)
...
ST_WITHIN(
g1,
TRY_TO_GEOGRAPHY('POLYGON((-1 -1, -1 4, 4 4, 4 -1, -1 -1))'))
...
ST_COVERS(
g1,
ST_GEOGPOINTFROMGEOHASH('s00'))