有啥建议可以加快慢速地理查询吗?
Posted
技术标签:
【中文标题】有啥建议可以加快慢速地理查询吗?【英文标题】:Any suggestions to speed up slow geography query?有什么建议可以加快慢速地理查询吗? 【发布时间】:2018-04-20 13:16:50 【问题描述】:我们有一张客户表,每个人的位置作为地理列,还有一个分支机构表,每个人的位置作为地理列(我们从纬度和经度列填充地理列)
我们需要运行一个查询(视图),旨在根据 Geography 列向每个客户显示最近的分支机构,并且它可以很好地处理几千个客户。我们刚刚收到一项需要与 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 中?目前还没有想到...
感谢您的任何建议!
【问题讨论】:
这可能有助于显示所有相关表的架构,包括任何索引等。 一般来说,你不会通过移动部分来优化查询(如果原始逻辑是合理的,并且更新的版本在逻辑上是等效的,那么如果优化器正在做它的工作,那么更新的版本应该产生与原始版本相同的执行计划)。 SQL 中主要的优化工具是索引。您是否在表上定义了空间索引? 减少要测试的初始人口。看看“项目 2”***.com/questions/45869613/… 交叉连接是性能杀手,我会尝试做一些内部连接,但不知道表结构和定义很难帮助。 表非常简单:Cust_Locations 有 CustNum(整数,PK)和 CustLoc(地理),Branch_Locations 有 BranchNum(整数,PK)和 BranchLoc(地理)。没有空间索引;应该有吗? 【参考方案1】:所以,你在这里做的是计算每个点到另一个点的距离,然后进行排名。实际上,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,,但归根结底,最重要的一点是创建空间索引并确保使用它们。
【讨论】:
以上是关于有啥建议可以加快慢速地理查询吗?的主要内容,如果未能解决你的问题,请参考以下文章
为啥要避免动态 SQL 查询?有啥建议可以删除坏的部分并使用这些吗?