创建空间索引需指定BOUNDING_BOX?如何优化空间相交查询
1. 手动指定空间索引的BOUNDING_BOX
首先需要获取表中几何数据的实际范围,再将该范围作为BOUNDING_BOX参数传入索引创建语句:
步骤1:查询数据的最小外接矩形范围
执行以下SQL获取LAND_V1表Shape列的边界值:
SELECT MIN(Shape.STEnvelope().STX) AS xmin, MIN(Shape.STEnvelope().STY) AS ymin, MAX(Shape.STEnvelope().STPointN(2).STX) AS xmax, MAX(Shape.STEnvelope().STPointN(2).STY) AS ymax FROM LAND_V1;
(注:STEnvelope()返回几何对象的最小外接矩形,STPointN(2)对应矩形的右上角点,也可用STEndPoint()替代)
步骤2:创建带BOUNDING_BOX的空间索引
将查询得到的xmin、ymin、xmax、ymax替换到语句中:
CREATE SPATIAL INDEX SPIX_Shape_LAND_V1 ON LAND_V1(Shape) USING geometry_auto_grid WITH (BOUNDING_BOX = (xmin, ymin, xmax, ymax));
关键提示:百万行的LAND_V2表必须同步创建空间索引,重复上述步骤为其生成对应索引。
2. BOUNDING_BOX对相交区域计算的影响
指定BOUNDING_BOX不会影响最终的相交区域计算结果。它只是空间索引用来快速过滤完全不相交对象的范围阈值,实际的相交判断(STIntersects)和相交区域计算(STIntersection)均基于原始几何图形的精确坐标,与索引的BOUNDING_BOX无关。
3. GeomType对BOUNDING_BOX指定的影响
无论几何类型是Polygon、MultiPolygon还是GeometryCollection,BOUNDING_BOX的指定逻辑完全一致——只需覆盖表中所有几何对象的最小外接矩形范围即可。不同几何类型的对象,其STEnvelope()都会返回自身的最小外接矩形,无需针对类型做特殊处理,索引引擎会自动适配。
4. 查询语句的优化建议
核心优化:为两张表都创建空间索引
只有LAND_V1和LAND_V2都配置了空间索引,查询的JOIN条件STIntersects(s2.Shape, s1.Shape) = 1才能利用索引快速过滤不相交记录,避免全表扫描。
可选优化:调整查询驱动表
如果LAND_V1的行数远少于LAND_V2,可强制查询优化器以LAND_V1为驱动表,减少对LAND_V2的索引查找次数:
SELECT s1.*, s2.Shape.STIntersection(s1.Shape) AS SHAPE FROM LAND_V1 s1 INNER LOOP JOIN LAND_V2 s2 ON s1.Shape.STIntersects(s2.Shape) = 1;
(注:LOOP JOIN适用于小表驱动大表的场景,若LAND_V1行数较多,可改用HASH JOIN或MERGE JOIN,具体以执行计划为准)
内容的提问来源于stack exchange,提问作者HR1

