【问题标题】:How to use spatial index to test procedure in sql server?如何使用空间索引在 sql server 中测试程序?
【发布时间】:2021-07-24 15:22:21
【问题描述】:

我有一个程序来返回最近的 vachile 列表,我使用空间索引来测试这个程序 我的程序是:

create procedure    [dbo].[p_search_vehicle]
@IdCustomer int,
 @idGroupVehicle int = null,
 @ResultCount int= null,
 @Radiant int= null 
 as
 begin
 if @IdCustomer is null
    begin
        print 'The argument cannot be null'
        return 
    end
 declare @start geography
 SET @start = (select location from Customer where idCustomer=@idCustomer )
 ---@Result null group null radiant null
    if @ResultCount is null and @idGroupVehicle is null and @Radiant is null
    select top 10 idVehicle,idGroupVehicle,brand,model,maxRange,weight,maxSpeed, nameLocation , @start.STDistance(locationVehicle)/1000 as distanceInKm
        from Vehicle 
            where (@start.STDistance(locationVehicle)/1000 is not null)
            order by @start.STDistance(locationVehicle)/1000 asc
             ---@Result null  radiant null
            else if @ResultCount is null and @Radiant is null
    select  top 10 idVehicle,idGroupVehicle,brand,model,maxRange,weight,maxSpeed, nameLocation , @start.STDistance(locationVehicle)/1000 as distanceInKm
        from Vehicle 
            where  idGroupVehicle= @idGroupVehicle and (@start.STDistance(locationVehicle)/1000  is not null)
            order by @start.STDistance(locationVehicle)/1000 asc
             ---@Radiant null  
            else if @Radiant is null
    select TOP(@ResultCount) idVehicle,idGroupVehicle,brand,model,maxRange,weight,maxSpeed, nameLocation , @start.STDistance(locationVehicle)/1000 as distanceInKm
        from Vehicle 
            where idGroupVehicle= @idGroupVehicle  and  (@start.STDistance(locationVehicle)/1000  is not null)
            order by @start.STDistance(locationVehicle)/1000 asc
             ---@@idGroupVehicle  null @Radiant is null
            else if  @idGroupVehicle is null and @Radiant is null
    select TOP(@ResultCount) idVehicle,idGroupVehicle,brand,model,maxRange,weight,maxSpeed, nameLocation , @start.STDistance(locationVehicle)/1000 as distanceInKm
        from Vehicle 
            where  (@start.STDistance(locationVehicle)/1000  is not null)
            order by @start.STDistance(locationVehicle)/1000 asc
            ---@idGroupVehicle is null and @ResultCount is null
            else if  @idGroupVehicle is null and @ResultCount is null
    select top 10 idVehicle,idGroupVehicle,brand,model,maxRange,weight,maxSpeed, nameLocation , @start.STDistance(locationVehicle)/1000 as distanceInKm
        from Vehicle 
            where  (@start.STDistance(locationVehicle)/1000   <= @Radiant)
            order by @start.STDistance(locationVehicle)/1000 asc
        --- @idGroupVehicle is null 
            else if  @idGroupVehicle is null 
    select TOP(@ResultCount) idVehicle,idGroupVehicle,brand,model,maxRange,weight,maxSpeed, nameLocation , @start.STDistance(locationVehicle)/1000 as distanceInKm
        from Vehicle 
            where  (@start.STDistance(locationVehicle)/1000   <= @Radiant)
            order by @start.STDistance(locationVehicle)/1000 asc
            --- @Result is null 
            else if  @ResultCount is null 
    select TOP(10) idVehicle,idGroupVehicle,brand,model,maxRange,weight,maxSpeed, nameLocation , @start.STDistance(locationVehicle)/1000 as distanceInKm
        from Vehicle 
            where  idGroupVehicle= @idGroupVehicle and  (@start.STDistance(locationVehicle)/1000   <= @Radiant)
            order by @start.STDistance(locationVehicle)/1000 asc
            --- all options
    else
    select TOP(@ResultCount) idVehicle,idGroupVehicle,brand,model,maxRange,weight,maxSpeed, nameLocation , @start.STDistance(locationVehicle)/1000 as distanceInKm
        from Vehicle 
            where idGroupVehicle= @idGroupVehicle  and  (@start.STDistance(locationVehicle)/1000  <= @Radiant)
            order by @start.STDistance(locationVehicle)/1000 asc
 end
GO

我有表 Vehicle 并且在我的表中我有 locationVehicle 这条记录有地理类型并且在这条记录上我有这样的空间索引

CREATE SPATIAL INDEX [SIndx_Vehicle_locationVehicle] ON [dbo].[Vehicle]
(
    [locationVehicle]
)USING  GEOGRAPHY_AUTO_GRID 
WITH (
CELLS_PER_OBJECT = 12, PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

但是当我测试我的程序以查看我的计划时,我在这个计划中没有看到我的空间索引,我不知道为什么有人可以告诉我为什么我没有看到执行计划中的空间索引? 我只看到这个表的 pk 键

【问题讨论】:

  • where (@start.STDistance(locationVehicle)/1000 is not null)?为什么/1000NULL/1000 = NULL 其中{any non-NULL value} / 1000 = {a non-NULL value}/1000不会在这里帮助 RDBMS。
  • /1000 因为我想在返回时看到公里,如果我删除 /1000 会更好吗?
  • 这不存在为什么它在WHERE 虽然@Konrad。
  • 什么在哪里不存在? @Lamu 我想以公里为单位查看与车辆的距离,并且距离不能为空
  • 但我必须从 Vehicle [WITH(INDEX())] 中使用类似的东西?

标签: sql sql-server indexing spatial


【解决方案1】:

将 cmets 的长期讨论转化为答案,在您的查询中的几个地方将米转换为公里可能是这里的原因。让我们按顺序浏览它们:

  1. @start.STDistance(locationVehicle)/1000 is not null。写成@start is not null and locationVechicle is not null 会更好吗?也就是说,如果两个地理空间点存在,它们之间会有一个距离(可能是 0,但即使这样仍然不为空`。

  2. order by @start.STDistance(locationVehicle)/1000。最好写成order by @start.STDistance(locationVehicle)。如所写,SQL 必须计算@start 和表中每个点之间的距离,除以 1000,然后使用新计算的度量进行排序。简而言之,该部门已经变成了不可SARGable。

也就是说,我还将完全从数据库中删除米到公里的转换,并将其转移到您的应用程序层。这是一个很小的计算负担,这仍然是昂贵数据库服务器上的 CPU 周期,可以在更便宜(且更容易扩展)的应用层上完成。

【讨论】:

  • 也就是说,您建议将select @ start.STDistance (locationVehicle) / 1000 所在的行删除/1000 并将where (@ start.STDistance (locationVehicle) / 1000 is not null) 所在的行更改为@start is not null and locationVechicle is not null 并按顺序将order by @ start.STDistance (locationVehicle) 删除/1000 吗?好的,我会检查一下,但是当我使用提示时,我的执行计划中有一个空间索引
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-10
  • 1970-01-01
  • 2012-08-10
相关资源
最近更新 更多