空间索引概述

SQL Server 2008 及更高版本支持空间数据。这包括对平面空间数据类型 geometry 的支持,该数据类型支持欧几里得坐标系统中的几何数据(点、线和多边形)。geography 数据类型表示地球表面某区域上的地理对象,如一片陆地。geography 列的空间索引会将地理数据映射到二维非欧几里得空间。

空间索引是对包含空间数据的表列(“空间列”)定义的。每个空间索引指向一个有限空间。例如,geometry 列的索引指向平面上用户指定的矩形区域。

将索引空间分解成网格层次结构

在 SQL Server 2008 中,空间索引使用 B 树构建而成,也就是说,这些索引必须按 B 树的线性顺序表示二维空间数据。因此,将数据读入空间索引之前,SQL Server 2008 先实现对空间的分层均匀分解。索引创建过程会将空间分解成一个四级“网格层次结构”。这些级别指的是“第 1 级”(顶级)、“第 2 级”、“第 3 级”和“第 4 级”。

每个后续级别都会进一步分解其上一级,因此上一级别的每个单元都包含下一级别的整个网格。在给定级别上,所有网格沿两个轴都有相同数目的单元(例如 4x4 或 8x8),并且单元的大小都相同。

下图显示了网格层次结构每个级别的右上角单元被分解成 4x4 网格的情况。事实上,所有单元都是以这种方式分解的。因此,以此为例,将一个空间分解成四个级别的 4x4 网格实际上会总共产生 65,536 个第四级单元。

递归分割的四个级别

注意注意

针对空间索引进行的空间分解与应用程序数据使用的度量单位无关。

网格层次结构的单元是利用多种 Hilbert 空间填充曲线以线性方式编号的。然而,出于演示目的,这里使用的是简单的按行编号,而不是由 Hilbert 曲线实际产生的编号。在下图中,几个表示建筑物的多边形和表示街道的线已经放进了一个 4x4 的 1 级网格中。第 1 级单元的编号为 1 到 16,编号从左上角的单元开始。

放置在 4x4 第 1 级网格上的多边形和直线

网格密度

沿网格轴的单元数目确定了网格的“密度”:单元数目越大,网格的密度越大。例如,8x8 网格(产生 64 个单元)的密度就大于 4x4 网格(产生 16 个单元)的密度。网格密度是以每个级别为基础定义的。

CREATE SPATIAL INDEXTransact-SQL 语句支持 GRIDS 子句,使用该子句可以在不同级别指定不同的网格密度。可以使用下列关键字之一指定给定级别的网格密度:

关键字

网格配置

单元数目

LOW

4X4

16

MEDIUM

8X8

64

HIGH

16X16

256

默认设置所有级别都为 MEDIUM。

您可以通过指定非默认的网格密度控制分解过程。例如,在不同级别指定不同网格密度对于基于索引空间的大小和空间列中的对象来优化索引可能非常有用。

注意注意

空间索引的网格密度显示在 sys.spatial_index_tessellations 目录视图的 level_1_grid、level_2_grid、level_3_grid 和 level_4_grid 列中。

分割

将索引空间分解成网格层次结构后,空间索引将逐行读取空间列中的数据。读取空间对象(或实例)的数据后,空间索引将为该对象执行“分割过程”。分割过程通过将对象与其接触的网格单元集(“接触单元”)相关联使该对象适合网格层次结构。从网格层次结构的第 1 级开始,分割过程以“广度优先”方式对整个级别进行处理。在可能的情况下,此过程可以连续处理所有四个级别,一次处理一个级别。

分割过程的输出为对象的空间索引中所记录的接触单元集。通过引用这些已记录单元,空间索引可以确定该对象在空间中相对于空间列中也存储在索引中的其他对象的位置。

分割规则

为了限制为对象记录的接触单元数,分割过程采用了几个分割规则。这些规则确定分割过程的深度以及在索引中记录哪些接触单元。

这些规则如下:

  • 覆盖规则

    如果一个对象完全盖住了某个单元,则称该单元由该对象所“覆盖”。被覆盖的单元会参与计数,但不进行分割。此规则应用于网格层次结构的所有级别。覆盖规则简化了分割过程,并减少了空间索引记录的数据量。

  • 每对象单元数规则

    此规则强制执行“每对象单元数限制”,这将确定可以为每个对象计数的最大单元数(第 1 级除外)。在较低级别,每对象单元数规则会控制可以记录的有关对象的信息量。

  • 最深单元规则

    最深单元规则通过只记录已为对象分割的最底部单元来生成该对象的最近似对象。父单元不计入每对象单元数,这些单元不记录在索引中。

这些分割规则依次逐步应用于每个网格级别。此部分的其余内容更详细地介绍了这些分割规则。

覆盖规则

如果一个对象完全盖住了某个单元,则称该单元由该对象所“覆盖”。例如,在下图中,一个第 2 级单元 15.11 完全由八边形的中间部分所覆盖。

表面优化

被覆盖的单元会参与计数并记录在索引中,但不再进行分割。

每对象单元数规则

每个对象的分割程度主要取决于空间索引的“每对象单元数限制”。此限制确定了对于每个对象分割可以计数的最大单元数。然而,请注意,每对象单元数规则不对第 1 级强制执行,因此可能超出此限制。如果第 1 级计数达到(或超出)每对象单元数限制,则在较低级别不再进行分割。

只要计数低于每对象单元数限制,分割过程就将继续。从编号最低的接触单元(例如上图中的单元 15.6)开始,此过程将测试每个单元以评估是对其进行计数还是进行分割。如果分割某单元将超出每对象单元数限制,将对该单元进行计数而不进行分割。否则,将对该单元进行分割,而对由对象接触的较低级别的单元进行计数。分割过程将以这种方式在整个级别的广度范围内继续进行。此过程对低级别网格的分割单元依次逐步进行重复,直至达到限制或不再有要计数的单元为止。

例如,上图显示了一个完全适合第 1 级网格的单元 15 的八边形。在此图中,单元 15 已进行分割,将八边形分成了九个二级单元。此图假定每对象单元数限制为 9 或更大。然而,如果每对象单元数限制为 8 或更小,则单元 15 将不进行分割,而只为该对象对单元 15 进行计数。

默认情况下,每对象单元数限制为每个对象 16 个单元,这将在大多数空间索引的空间和精度之间提供一个令人满意的折中方案。然而,CREATE SPATIAL INDEXTransact-SQL 语句支持 CELLS_PER_OBJECT**=**n 子句,使用该子句可以指定介于 1 和 8192(包含这两者)之间的每对象单元数限制。

注意注意

空间索引的 cells_per_object 设置显示在 sys.spatial_index_tessellations 目录视图中。

最深单元规则

最深单元规则利用每个较低级别单元属于其上级单元这一事实:第 4 级单元属于第 3 级单元,第 3 级单元属于第 2 级单元,第 2 级单元属于第 1 级单元。例如,属于单元 1.1.1.1 的对象也属于单元 1.1.1、单元 1.1 以及单元 1。这种单元层次结构关系知识已内置于查询处理器中。因此,只有最深级别的单元需要记录在索引中,从而最大限度地减少了索引需要存储的信息。

在下图中,相对较小的菱形多边形被分割。索引使用默认的每对象单元数限制 16,此对象较小,未达到该限制。因此,分割一直下至第 4 级。此多边形驻留在以下的第 1 级到第 3 级的单元中:4、4.4 以及 4.4.10 和 4.4.14。然而,使用最深单元规则,分割将仅对十二个位于第 4 级的单元进行计数:4.4.10.13-15 以及 4.4.14.1-3、4.4.14.5-7 和 4.4.14.9-11。

最深单元优化

分割方案

空间索引的行为部分取决于“分割方案”。分割方案特定于数据类型。在 SQL Server 2008 中,空间索引支持两种分割方案:

  • “几何图形网格分割”,这是适用于 geometry 数据类型的方案。

  • 地理网格分割方案,该方案适用于数据类型为 geography 的列。

注意注意

空间索引的 tessellation_scheme 设置显示在 sys.spatial_index_tessellations 目录视图中。

几何图形网格分割方案

几何图形网格分割是适用于 geometry 数据类型的默认分割方案。在 SQL Server 2008 中,它是唯一的此类分割方案。本部分讨论了与使用空间索引有关的几何图形网格分割的几个方面:支持的方法和边界框。

注意注意

您可以使用 CREATE SPATIAL INDEXTransact-SQL 语句的 USING GEOMETRY_GRID 子句显式指定此分割方案。

支持的几何图形方法

空间索引旨在通过充当对象筛选器来减少将面向集合的方法应用于空间列的开销。geometry 数据类型提供了一些内置的方法,以构造用于描述几何对象的 geometry 实例并使用这些实例。在某些条件下,空间索引支持多种面向集合的几何图形方法,如 STIntersects()STTouches()

有关由空间索引提供的几何图形方法支持的详细信息,请参阅空间索引支持的几何图形方法

边界框

几何数据占有的平面可以是无限的。然而,在 SQL Server 2008 中,空间索引需要有限空间。为了建立有限空间以用于分解,几何图形网格分割方案需要矩形“边界框”。该边界框由四个坐标 (x-min,y-min)(x-max,y-max) 定义,这些坐标存储为空间索引的属性。这些坐标所表示的意义如下:

  • x-min 是边界框左下角的 x 坐标。

  • y-min 是左下角的 y 坐标。

  • x-max 是右上角的 x 坐标。

  • y-max 是右上角的 y 坐标。

注意注意

这些坐标通过 CREATE SPATIAL INDEXTransact-SQL 语句的 BOUNDING_BOX 子句指定。

(x-min,y-min)(x-max,y-max) 坐标确定边界框的位置和尺寸。边界框的外部空间视作一个编号为 0 的单元。

空间索引将分解边界框的内部空间。网格层次结构的第 1 级网格将填充边界框。若要在网格层次结构中放置几何对象,空间索引会将该对象的坐标与边界框的坐标进行比较。

下图显示了由边界框的 (x-min,y-min)(x-max,y-max) 坐标定义的点。网格层次结构的顶级显示为 4x4 网格。出于演示的目的,这里省略了较低级别。边界框的外部空间用零 (0) 指示。请注意,对象“A”部分超出了边界框,对象“B”完全位于边界框外部,即单元 0 中。

显示坐标和单元 0 的边界框。

边界框与应用程序空间数据的某些部分相对应。索引的边界框是完全包含存储在空间列中的数据还是只包含其中部分数据取决于应用程序。只有针对完全位于边界框内部的对象的计算操作才会受益于空间索引。因此,若要获得 geometry 列的空间索引所能提供的最大优势,您需要指定一个包含所有或大多数对象的边界框。

注意注意

空间索引的网格密度显示在 sys.spatial_index_tessellations 目录视图的 bounding_box_xmin、bounding_box_ymin、bounding_box_xmax 和 bounding_box_ymax 列中。

地理网格分割方案

此分割方案仅适用于 geography 列。此部分总结了地理网格分割支持的方法,并讨论了如何将测量空间投影到平面上,该平面随后将分解成网格层次结构。

注意注意

您可以使用 CREATE SPATIAL INDEXTransact-SQL 语句的 USING GEOGRAPHY_GRID 子句显式指定此分割方案。

支持的地理方法

geography 数据类型提供了一些内置的方法,用来构造和操作描述地理对象的 geography“实例”。在某些条件下,空间索引支持以下面向集合的地理方法:STIntersects()STEquals()STDistance()。geography 数据类型列上的空间索引会筛选对象,并降低将这些方法应用于空间数据的性能和查询开销。

有关由空间索引提供的地理方法支持的详细信息,请参阅空间索引支持的地域方法

将测量空间投影到平面上

对 geography 实例(对象)的计算将包含对象的空间视作测量椭圆体。若要分解此空间,地理网格分割方案将椭圆体表面分为上半球和下半球,然后执行下列步骤:

  1. 将每个半球投影在四边形棱锥图面上。

  2. 将两个棱锥图平展开。

  3. 联接平展的棱锥图以形成非欧几里得平面。

下图显示了此三步分解过程的示意图。在棱锥图中,虚线表示每个棱锥图的四个面的边界。步骤 1 和 2 显示测量椭圆体,使用一条绿色水平线表示赤道经线,使用一系列绿色垂直线表示若干条纬线。步骤 1 显示要投影在两个半球上的棱锥图。步骤 2 显示要平展的棱锥图。步骤 3 显示平展的棱锥图,这些棱锥图已组合起来形成一个平面,显示出许多投影的经线。请注意,这些投影线伸直后长度不一,具体取决于它们落在棱锥图上的位置。

椭圆体在平面上的投影

空间投影到平面上之后,此平面将会分解成四级网格层次结构。不同级别可以使用不同的网格密度。下图显示了已分解成一个 4x4 的 1 级网格后的平面。出于演示目的,这里省略了网格层次结构的较低级别。事实上,此平面完全分解成了一个四级网格层次结构。分解过程完成后,将逐行从 geography 列读取地理数据,并为每个对象依次执行分割过程。

第 1 级地理网格

空间索引支持

可以仅对空间列创建空间索引。可以对支持空间索引的表的任何空间列创建空间索引,并可以对给定的空间列创建多个空间索引。有关对空间索引的限制的详细信息,请参阅对空间索引的限制