Azure SQL 服务器空间索引错误无法创建...因为已计算列
Azure SQL Server Spatial Index Error Cannot create...because column is computed
[更新] 我尝试了下面的索引定义并收到以下错误消息:
Cannot create primary xml, selective xml or spatial index 'SI_Property' on table 'BTSOne.dbo.Properties', column 'Point', because the column is computed.
这是有道理的,但现在我回到原点。
我尝试这样做的原因是什么?因为查询超时。我为所有其他查询设置了索引,但空间查询除外,这是执行的主要查询类型。
我对在哪些列上创建空间索引有点困惑。我很担心,因为一些记录缺少影响点列、索引列的经度和纬度值(默认为零)。起初我以为我可以在点列上创建索引,但阅读有关此事的文章建议我使用多个列。我读得越多,我就越困惑。此外,还有正确设置网格的问题。经验法则似乎是将它们设置为高。
这些是相关的 table 列:
[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 服务器实例,所以我不我不想耗尽我的重试次数限制:-)。
谢谢!
空间索引确实需要一点时间来适应,但是一旦你习惯了,它们就非常简单了。
首先,只能在空间列上创建空间索引 - 即 GEOMETRY
或 GEOGRAPHY
类型的列。在您的实例中,您只有一个列“[Point]”,因此这是您应该并且可以编制索引的唯一列。
当 运行 查询涉及空间数据时,生成的查询计划通常非常有效,对 WHERE 子句的那部分使用空间索引,对 WHERE 子句的其他部分使用其他非空间索引.
至于网格级别,不幸的是,它可能是反复试验,因为它最终取决于您的数据。但是,当您开始使用这些设置时,我发现您通常只能节省几毫秒——在大多数情况下。像在 HHHH 一样开始,每个对象有 16 个单元格。如果您对结果不满意,请检查查询计划以确保它已被使用,如果是,请对其进行调整。
如果你真的想了解空间索引,我建议你查看 Alistair Aitchison 的 "Pro Spatial with SQL Server 2012"。这确实是在 SQL 中使用空间数据的圣经,Alistair 在这方面做得非常出色。
[更新] 我尝试了下面的索引定义并收到以下错误消息:
Cannot create primary xml, selective xml or spatial index 'SI_Property' on table 'BTSOne.dbo.Properties', column 'Point', because the column is computed.
这是有道理的,但现在我回到原点。
我尝试这样做的原因是什么?因为查询超时。我为所有其他查询设置了索引,但空间查询除外,这是执行的主要查询类型。
我对在哪些列上创建空间索引有点困惑。我很担心,因为一些记录缺少影响点列、索引列的经度和纬度值(默认为零)。起初我以为我可以在点列上创建索引,但阅读有关此事的文章建议我使用多个列。我读得越多,我就越困惑。此外,还有正确设置网格的问题。经验法则似乎是将它们设置为高。
这些是相关的 table 列:
[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 服务器实例,所以我不我不想耗尽我的重试次数限制:-)。
谢谢!
空间索引确实需要一点时间来适应,但是一旦你习惯了,它们就非常简单了。
首先,只能在空间列上创建空间索引 - 即 GEOMETRY
或 GEOGRAPHY
类型的列。在您的实例中,您只有一个列“[Point]”,因此这是您应该并且可以编制索引的唯一列。
当 运行 查询涉及空间数据时,生成的查询计划通常非常有效,对 WHERE 子句的那部分使用空间索引,对 WHERE 子句的其他部分使用其他非空间索引.
至于网格级别,不幸的是,它可能是反复试验,因为它最终取决于您的数据。但是,当您开始使用这些设置时,我发现您通常只能节省几毫秒——在大多数情况下。像在 HHHH 一样开始,每个对象有 16 个单元格。如果您对结果不满意,请检查查询计划以确保它已被使用,如果是,请对其进行调整。
如果你真的想了解空间索引,我建议你查看 Alistair Aitchison 的 "Pro Spatial with SQL Server 2012"。这确实是在 SQL 中使用空间数据的圣经,Alistair 在这方面做得非常出色。