我有一个以 json 字符串作为参数的查询。json 是一个纬度、经度对数组。示例输入可能如下所示。
declare @json nvarchar(max)= N'[[40.7592024,-73.9771259],[40.7126492,-74.0120867]
,[41.8662374,-87.6908788],[37.784873,-122.4056546]]';
Run Code Online (Sandbox Code Playgroud)
它调用 TVF 来计算地理点周围 1、3、5、10 英里距离处的 POI 数量。
create or alter function [dbo].[fn_poi_in_dist](@geo geography)
returns table
with schemabinding as
return
select count_1 = sum(iif(LatLong.STDistance(@geo) <= 1609.344e * 1,1,0e))
,count_3 = sum(iif(LatLong.STDistance(@geo) <= 1609.344e * 3,1,0e))
,count_5 = sum(iif(LatLong.STDistance(@geo) <= 1609.344e * 5,1,0e))
,count_10 = count(*)
from dbo.point_of_interest
where LatLong.STDistance(@geo) <= 1609.344e * 10
Run Code Online (Sandbox Code Playgroud)
json 查询的目的是批量调用此函数。如果我这样称呼它,则性能非常差,仅用了近 10 秒就获得了 4 分:
select row=[key]
,count_1
,count_3
,count_5
,count_10
from openjson(@json)
cross apply dbo.fn_poi_in_dist(
geography::Point(
convert(float,json_value(value,'$[0]')) …
Run Code Online (Sandbox Code Playgroud) 我有一些表,其中包含存储为 lat long 对的属性的事务。(然后在我的示例架构中有更多的列和数据点)。
一个常见的请求是查找特定点 X 英里范围内发生的交易,并且只检索附近每个房产发生的 5 个最近的交易。
为了完成这项工作,我决定添加一个视图来封装最新的逻辑:
create or alter view dbo.v_example
with schemabinding as
select example_id
,transaction_dt
,latitude
,longitude
,latlong
,most_recent= iif(row_number() over (partition by latitude,longitude order by transaction_dt desc) < 5,1,null)
from dbo.example;
Run Code Online (Sandbox Code Playgroud)
所以一个查询可能看起来像这样:
create or alter view dbo.v_example
with schemabinding as
select example_id
,transaction_dt
,latitude
,longitude
,latlong
,most_recent= iif(row_number() over (partition by latitude,longitude order by transaction_dt desc) < 5,1,null)
from dbo.example;
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我通过视图查询时,SQL Server 不想使用空间索引。如果我删除schemabinding
并尝试在视图上添加提示,我会发现查询处理器无法创建计划。
如何封装逻辑并仍然让它使用我的空间索引?
该表要大得多,扫描它然后进行聚集索引查找然后逐点查找要慢得多。
我注意到我有一个不断重置范围配置的数据库,即 maxdop。
是否有任何日志显示谁或什么进程导致这些配置更改?我使用的是 Microsoft SQL Server 2016 (SP1-CU7-GDR) (KB4057119) - 13.0.4466.4