有什么建议加快缓慢的地理查询?

时间:2018-04-20 13:16:51

标签: sql sql-server tsql geography

我们有一个客户表,每个人的位置都是地理列,还有一个分支办公室表,每个人的位置都是地理列(我们从纬度和经度列填充地理列)< / em>的

我们需要运行一个查询(视图),该查询旨在根据地理列显示每个客户最近的分支机构,并且它可以与几千个客户一起运行。我们刚收到一份需要与700,000名客户合作的大工作,需要 小时 才能运行。任何人都可以建议任何加速这个SQL的方法吗?

WITH CLOSEST AS (
    SELECT *, ROW_NUMBER() 
    OVER (
        PARTITION BY CustNum
        ORDER BY Miles
    ) AS RowNo 
    FROM 
(
SELECT 
CustNum,
BranchNum, 
CONVERT(DECIMAL(10, 6), (BranchLoc.STDistance(CustLoc)) / 1609.344) AS Miles
FROM 
Branch_Locations
CROSS JOIN
Cust_Locations
) AS T
)
SELECT TOP 100 PERCENT CustNum, BranchNum, Miles, RowNo FROM CLOSEST WHERE RowNo = 1 ORDER BY CustNum, MILES

有没有办法将距离比较放入JOIN?到目前为止,没有任何想法......

感谢您的任何建议!

1 个答案:

答案 0 :(得分:0)

因此,您在这里所做的是计算每个点到另一个点的距离,然后进行排名。实际上,SQL Server Spatial的设置完全不需要。

您要做的第一件事是在每个表上创建一个空间索引;有关如何执行此操作的文档,请参见here.。请不要担心此处的特定参数,尽管您可以通过调整它们(绝对具有空间索引 )来绝对提高性能,大大提高性能。

您要做的第二件事是确保使用空间索引。可以找到有关如何确保这种情况发生的文档here. 请确保您过滤掉任何空的空间信息!

因此,到目前为止,这是在一个较长的表列表中求点并找到最接近点的一种方法。但这是SQL Server,我们要以此为基础!

我的建议是使用一些先验知识,并以此来编写查询。

WITH CLOSEST AS (
  SELECT 
    C.CustNum,
    B.BranchNum, 
    ROW_NUMBER() OVER (PARTITION BY C.CustNum ORDER BY B.BranchLoc.STDistance(C.CustLoc)/1609.344 ASC) AS Miles
  FROM 
    Branch_Locations B
  INNER JOIN
    Cust_Locations C
  ON
    B.BranchLoc.STDistance(C.CustLoc)/1609.344 < 100 --100 miles as a maximum search distance is a reasonable number to me
  WHERE
    B.BranchLoc IS NOT NULL
    AND C.CustLoc IS NOT NULL
) AS T

SELECT 
  CustNum, 
  BranchNum, 
  Miles, 
  RowNo 
FROM 
  CLOSEST 
WHERE 
  RowNo = 1 
ORDER BY 
  CustNum, 
  MILES

您还可以使用其他技术,例如我的回复here,,但最重要的要诀是创建空间索引并确保使用它们。