Azure SQL Server 空间索引错误无法创建...因为已计算列

Posted

技术标签:

【中文标题】Azure SQL Server 空间索引错误无法创建...因为已计算列【英文标题】:Azure SQL Server Spatial Index Error Cannot create...because column is computed 【发布时间】:2015-04-06 01:29:11 【问题描述】:

[UPDATE] 我尝试了下面的索引定义并收到以下错误消息:

  Cannot create primary xml, selective xml or spatial index 'SI_Property' on table 'BTSOne.dbo.Properties', column 'Point', because the column is computed.

这是有道理的,但现在我又回到了原点。

我尝试这样做的原因是什么?因为查询超时。我为所有其他查询设置了索引,但空间查询是执行的主要查询类型。

我对在哪些列上创建空间索引有点困惑。我很担心,因为某些记录缺少经度和纬度值(默认为零),这会影响点列、索引列。起初我以为我可以在点列上创建索引,但阅读有关此事的文章建议我使用多个列。我读得越多,我就越困惑。此外,还有正确设置网格的问题。经验法则似乎将它们设置为高。

这些是相关的表格列:

  [Latitude] [float] NULL CONSTRAINT [DF_Properties_Latitude]  DEFAULT ((0)),
  [Longitude] [float] NULL CONSTRAINT [DF_Properties_Longitude]  DEFAULT ((0)),
[Point]  AS ([geography]::Point([Latitude],[Longitude],[SRID])),
[SRID] [int] NULL CONSTRAINT [DF_Properties_SRID]  DEFAULT ((4326)),

这是存储过程的相关部分:

  DECLARE @SearchPoint as geography,
    @Region nvarchar(80)

  SET @SearchPoint = geography::Point(@Latitude, @Longitude, 4326)

  DECLARE @tempTable dbo.WorkingProperties

  SELECT [PropertyId] AS "Id", ISNULL([InnCode],'NA') AS "InnCode",  [UseName] AS "OfficeName", [Addr1] As "Address", [City]
  , [Zip] AS "PostalCode", [CountryCode], [Brand], [BrandCode] ,[Latitude],  [Longitude], 
  ([Point].STDistance(@SearchPoint)/1000) AS "Distance",
  NULL AS "ProjectType",'Properties' As "Source", [GlobalRMArea]
  FROM [BTSOne].[dbo].[Properties]
  WHERE [Point].STDistance(@SearchPoint) <= (@intRadiusKm * 1000)
  AND OpenStatus = 'Open'
  ORDER BY "Distance"

这就是我创建索引的方式:

  CREATE SPATIAL INDEX [SI_Property] ON [BTSOne].[dbo].[Properties]
  (
      [Point]
  )USING  GEOGRAPHY_GRID 
  WITH (GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH),    
  CELLS_PER_OBJECT = 16, 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

我在一个非常有限的访问环境中工作,所以我没有太多的试验和错误的奢侈,我没有直接访问 sql server 实例,所以我不想磨损我的重试限制:-)。

谢谢!

【问题讨论】:

【参考方案1】:

空间索引确实需要一点时间来适应,但是一旦你习惯了,它们就很简单了。

首先,空间索引只能在空间列上创建——即GEOMETRYGEOGRAPHY 类型的列。在您的实例中,您只有一列“[Point]”,因此这是您应该并且可以索引的唯一列。

在运行涉及空间数据的查询时,生成的查询计划通常非常有效,对 WHERE 子句的该部分使用空间索引,对 WHERE 子句的其他部分使用其他非空间索引。

对于网格级别,不幸的是,它可能会反复试验,因为最终取决于您的数据。但是,当您开始使用这些设置时,我经常发现您只节省了几毫秒——在大多数情况下。从 HHHH 开始,每个对象有 16 个单元格。如果您对结果不满意,请检查查询计划以确保它正在被使用,如果是,请调整它。

如果您真的想了解空间索引,我建议您查看Alistair Aitchison 的“Pro Spatial with SQL Server 2012”。这确实是在 SQL 中使用空间数据的圣经,Alistair 在这方面做得非常出色。

【讨论】:

@WillLopez 好的,但此时您的选择非常明显。要么忍受较差的性能并保留计算列,要么使其不计算并享受空间索引的好处。你是如何将数据输入到表中的?最好的解决方案是编辑插入以处理 Point 列的计算 - 而不是将其作为计算列。 @Jon_Bellamy 我听到了。我会试试的。

以上是关于Azure SQL Server 空间索引错误无法创建...因为已计算列的主要内容,如果未能解决你的问题,请参考以下文章

无法连接到新的Azure SQL Server实例

数据从SQL Server迁移到Azure Cosmos数据库后无法查看数据

Azure 网站上的 SQL Server CE

SP 执行时 SQL Server 2008 中的 QUOTED IDENTIFIER 错误

无法使用 PHP 和 Codeigniter 从 PHP Azure 连接到 SQL Server Azure

SQL Server 索引视图:无法创建聚集索引,因为选择列表包含聚合函数结果的表达式