我们有一个客户表,每个人的位置都是地理列,还有一个分支办公室表,每个人的位置都是地理列(我们从纬度和经度列填充地理列)< / 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?到目前为止,没有任何想法......
感谢您的任何建议!
答案 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,,但最重要的要诀是创建空间索引并确保使用它们。