【问题标题】:Query Optimization Problems (spatial)查询优化问题(空间)
【发布时间】:2015-06-24 22:45:13
【问题描述】:

我有两个包含空间数据的数据集。

数据集 1 有大约 15,000,000 条记录。 数据集 2 有大约 16,000,000 条记录。

两者都使用地理数据类型(GPS 坐标),所有记录都是点。

两个表都有空间索引,cells_per_object = 1,级别为 (HIGH, HIGH, HIGH, HIGH)

所有点都位于全球范围内的小区域(美国 1 个州)。这些点分布得足以保证使用地理而不是几何投影。

DECLARE @g GEOGRAPHY
SET @g = (SELECT TOP 1 GPSPoint FROM Dataset1)

EXEC sp_help_spatial_geography_index 'Dataset1', 'Dataset1_SpatialIndex', 0, @g

表演

propvalue-propname
       1-Total_Number_Of_ObjectCells_In_Level0_For_QuerySample
   28178-Total_Number_Of_ObjectCells_In_Level1_In_Index
       1-Total_Number_Of_ObjectCells_In_Level4_For_QuerySample
14923330-Total_Number_Of_ObjectCells_In_Level4_In_Index
       1-Total_Number_Of_Intersecting_ObjectCells_In_Level1_In_Index
       1-Total_Number_Of_Intersecting_ObjectCells_In_Level4_For_QuerySample
14923330-Total_Number_Of_Intersecting_ObjectCells_In_Level4_In_Index
       1-Total_Number_Of_Border_ObjectCells_In_Level0_For_QuerySample
   28177-Total_Number_Of_Border_ObjectCells_In_Level1_In_Index
     740-Number_Of_Rows_Selected_By_Primary_Filter
       0-Number_Of_Rows_Selected_By_Internal_Filter
     740-Number_Of_Times_Secondary_Filter_Is_Called
       1-Number_Of_Rows_Output
99.99504-Percentage_Of_Rows_NotSelected_By_Primary_Filter
       0-Percentage_Of_Primary_Filter_Rows_Selected_By_Internal_Filter
       0-Internal_Filter_Efficiency
0.135135-Primary_Filter_Efficiency  

这意味着查询

DECLARE @g GEOGRPAHY
SET @g = (SELECT TOP 1 GPSPoint FROM Dataset1)

SELECT TOP 1
  *
FROM
  Dataset2 D
WHERE
  @g.Filter(D.GPSPoint.STBuffer(1)) = 1

大约需要一个小时才能完成。

我也试过了

WITH TABLE1 AS (
  SELECT
    A.RecordID,
    B.RecordID,
    RANK() OVER (PARTITION BY A.RecordID ORDER BY A.GPSPoint.STDistance(B.GPSPoint) ASC) AS 'Ranking'
  FROM
    Dataset1 A
  INNER JOIN
    Dataset2 B
  ON
    B.GPSPoint.Filter(A.GPSPoint.STBuffer(1)) = 1
    AND A.GPSPoint.STDistance(B.GPSPoint) <= 50
)

SELECT 
  *
FROM
  TABLE1
WHERE
  Ranking = 1

最终速度提高了大约 1,000 倍,但按照这个速度,我想要做的事情需要运行六个月的查询才能完成。老实说,我现在不知道该怎么办。最终目标是对 dataset1 中的每条记录进行最近邻搜索,以找到 dataset2 中的最近点,但这样似乎是不可能的。

有没有人有什么想法可以提高这个过程的效率?

【问题讨论】:

    标签: sql sql-server spatial spatial-index


    【解决方案1】:

    试试这个:它基于MSDN 上的建议。

      SELECT TOP(1)
        A.RecordID,
        B.RecordID,
        A.GPSPoint.STDistance(B.GPSPoint) AS Distance
      FROM
        Dataset1 A
      INNER JOIN
        Dataset2 B
      ON
        A.GPSPoint.STDistance(B.GPSPoint) <= 50
        AND B.GPSPoint IS NOT NULL
      ORDER BY BY A.GPSPoint.STDistance(B.GPSPoint) ASC
    

    注意我已经删除了这个,先试试上面的查询,然后添加这些谓词,看看它是如何影响索引的。

    B.GPSPoint.Filter(A.GPSPoint.STBuffer(1)) = 1 
        AND 
    //or try B.GPSPoint.STIntersects(A.GPSPoint.STBuffer(1)) = 1
    

    最近邻查询必须满足以下要求才能使用空间索引:

    • 空间索引必须存在于其中一个空间列上,并且 STDistance() 方法必须在 WHERE 和 ORDER BY 子句中使用该列。
    • TOP 子句不能包含 PERCENT 语句。
    • WHERE 子句必须包含 STDistance() 方法
    • 如果 WHERE 子句中有多个谓词,则包含 STDistance() 方法的谓词必须通过 AND 连接词连接到其他谓词。 STDistance() 方法不能在 WHERE 子句的可选部分中。
    • ORDER BY 子句中的第一个表达式必须使用 STDistance() 方法。
    • ORDER BY 子句中第一个 STDistance() 表达式的排序顺序必须为 ASC。
    • 必须过滤掉所有 STDistance 返回 NULL 的行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      相关资源
      最近更新 更多