SQL 服务器空间索引设置
SQL Server Spatial Indexes Setup
我目前有两个表 cities 和 listings,都有一个名为 Position 的字段,这是一个空间字段。
我的问题是我是否正确设置了索引,还是应该 add/remove 一些?
对于我没有在地图上显示它们的城市,我只使用一个与城市相关的查询,那就是我使用 lat/long 并且我得到 50 个最近的城市,对于列表我也做最近的并且我像我在这里做的那样在地图上显示它们
对于这两个表,我每个都有 2 个索引,设置如下。
256 HHHH
/****** Object: Index [Position_Index] Script Date: 1/25/2015 3:56:50 PM ******/
CREATE SPATIAL INDEX [Position_Index] ON [dbo].[Listings]
(
[Position]
)USING GEOGRAPHY_GRID
WITH (GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH),
CELLS_PER_OBJECT = 256, 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
16HHHH
/****** Object: Index [Spatial_Index] Script Date: 1/25/2015 3:58:23 PM ******/
CREATE SPATIAL INDEX [Spatial_Index] ON [dbo].[Listings]
(
[Position]
)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 服务器 2012
每个 table 中的 Position 字段只需要一个索引。拥有 2 是多余的,并且从任何数据库写入这些字段的角度来看都会损害性能,因此必须同时更新这两个字段。您确实需要在两个 table 中都有索引,因为您正在寻找城市和列表中最近的点。
从哪一个入手,要看你用的是点还是面。
对于区域(即不仅仅是点),您应该从每个对象 16 个单元格开始,因为根据 MSDN
By default, the cells-per-object limit is 16 cells per object, which
provides a satisfactory trade-off between space and precision for most
spatial indexes.
我会将其应用于城市,看看您的查询执行情况。如果不满意,增加它(可能只是继续加倍)直到你看不到性能提升。出于上述原因,我想 16 应该对你来说很好,但它会非常特定于数据。同样,只有在您不使用积分的情况下才有意义。
如果您的数据只包含点(这在您的情况下似乎很可能,至少对于列表而言),那么 CPO 值并不重要,您应该通过将每个级别设置为 HIGH 来获得非常好的性能,因为您已经这样做了完毕。来自文章 here:
In the case of point data, it has been found in most, if not in all,
cases that spatial indexes with all grid levels set to HIGH outperform
other configurations. Since we are dealing with point data, the
CELLS_PER_OBJECT setting is irrelevant and can be set to any legal
value (1-8192) without effect.
参考资料
如果您还没有阅读这些文章,我强烈建议您阅读:
我同意麦迪逊所说的。
尽管我要补充一点,我发现大多数查询都需要提示才能使用空间索引,例如:
SELECT *
FROM geoTable WITH (INDEX (spatial_index))
WHERE geoColumn.STDistance(@g) < 100
请记住,如果您正在执行多个连接 and/or where 使用空间索引的子句实际上可能并不比扫描快,因此请针对不同的情况测试这两种情况。
如果您的表相当大(超过 100 万行),空间索引往往会变慢。考虑将它们拆分为单独的表,每个州或国家/地区,因为您无法对这些索引进行分区。
我目前有两个表 cities 和 listings,都有一个名为 Position 的字段,这是一个空间字段。 我的问题是我是否正确设置了索引,还是应该 add/remove 一些? 对于我没有在地图上显示它们的城市,我只使用一个与城市相关的查询,那就是我使用 lat/long 并且我得到 50 个最近的城市,对于列表我也做最近的并且我像我在这里做的那样在地图上显示它们
对于这两个表,我每个都有 2 个索引,设置如下。
256 HHHH
/****** Object: Index [Position_Index] Script Date: 1/25/2015 3:56:50 PM ******/
CREATE SPATIAL INDEX [Position_Index] ON [dbo].[Listings]
(
[Position]
)USING GEOGRAPHY_GRID
WITH (GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH),
CELLS_PER_OBJECT = 256, 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
16HHHH
/****** Object: Index [Spatial_Index] Script Date: 1/25/2015 3:58:23 PM ******/
CREATE SPATIAL INDEX [Spatial_Index] ON [dbo].[Listings]
(
[Position]
)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 服务器 2012
每个 table 中的 Position 字段只需要一个索引。拥有 2 是多余的,并且从任何数据库写入这些字段的角度来看都会损害性能,因此必须同时更新这两个字段。您确实需要在两个 table 中都有索引,因为您正在寻找城市和列表中最近的点。
从哪一个入手,要看你用的是点还是面。
对于区域(即不仅仅是点),您应该从每个对象 16 个单元格开始,因为根据 MSDN
By default, the cells-per-object limit is 16 cells per object, which provides a satisfactory trade-off between space and precision for most spatial indexes.
我会将其应用于城市,看看您的查询执行情况。如果不满意,增加它(可能只是继续加倍)直到你看不到性能提升。出于上述原因,我想 16 应该对你来说很好,但它会非常特定于数据。同样,只有在您不使用积分的情况下才有意义。
如果您的数据只包含点(这在您的情况下似乎很可能,至少对于列表而言),那么 CPO 值并不重要,您应该通过将每个级别设置为 HIGH 来获得非常好的性能,因为您已经这样做了完毕。来自文章 here:
In the case of point data, it has been found in most, if not in all, cases that spatial indexes with all grid levels set to HIGH outperform other configurations. Since we are dealing with point data, the CELLS_PER_OBJECT setting is irrelevant and can be set to any legal value (1-8192) without effect.
参考资料
如果您还没有阅读这些文章,我强烈建议您阅读:
我同意麦迪逊所说的。 尽管我要补充一点,我发现大多数查询都需要提示才能使用空间索引,例如:
SELECT *
FROM geoTable WITH (INDEX (spatial_index))
WHERE geoColumn.STDistance(@g) < 100
请记住,如果您正在执行多个连接 and/or where 使用空间索引的子句实际上可能并不比扫描快,因此请针对不同的情况测试这两种情况。
如果您的表相当大(超过 100 万行),空间索引往往会变慢。考虑将它们拆分为单独的表,每个州或国家/地区,因为您无法对这些索引进行分区。