【发布时间】:2017-05-09 06:59:46
【问题描述】:
我有一个性能查询最近的商店:
我们有一张表,其中包含一个国家/地区的大约 50,000 条记录(商店/销售点位置)。
每条记录都有location“地理”类型的列
[LOCATION_geo] [geography]
为了提高性能,我使用此语法在该位置列上创建了一个空间索引
CREATE SPATIAL INDEX [LOCATION_geoIndex]
ON [dbo].[StoreLocations] ([LOCATION_geo])
USING GEOGRAPHY_GRID
WITH (
GRIDS =(LEVEL_1 = MEDIUM,LEVEL_2 = MEDIUM,LEVEL_3 = MEDIUM,LEVEL_4 = MEDIUM),
CELLS_PER_OBJECT = 16, PAD_INDEX = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
我有一个存储过程来返回用户当前位置最近的 1000 个商店。
USE [CompanyDB]
GO
SET STATISTICS TIME ON;
GO
declare @point geography;
set @point = geography::Point(49.2471855, -123.1078987, 4326);
SELECT top (1000) [id]
,[Location_Name]
,[LOCATION_geo]from [MYDB].[dbo].[StoreLocations]
where [LOCATION_geo].STDistance(@point) <= 10000
ORDER BY [LOCATION_geo].STDistance(@point)
问题是查询总是需要 656 毫秒到 800 毫秒。这对于我们的网站来说是不可接受的性能,因为我们预计会有太多的同步调用。
(受影响的 1000 行)
SQL Server 执行时间:CPU 时间 = 923 毫秒,已用时间 = 1511 毫秒。
注意:大部分门店位于部分城市(约 10 个城市)。
我还注意到聚集索引查找成本 >= 总查询成本的 45%。
所以我的问题是有没有更好的方法来提高该查询的性能?
【问题讨论】:
-
是否使用了空间索引?你能确认它是通过执行计划使用的吗?
-
是的,它已被使用,成本为 8%,估计行大小为 17 B,已排序:真实,估计执行次数为 109.8。
-
另外,执行计划中的这个索引总是给出警告“没有统计的列:....SRID,....pk0”,其实我不知道是什么意思
-
我想如果你确定你正在使用索引,这是你可以获得的最好的性能。您可以考虑另一种解决方案 - 例如创建 10 个表用于存储每个大城市的位置,并创建一个表用于存储其余记录;然后,有了用户的坐标,计算出要查询哪些表;也许减少记录会提高性能;
-
网格分辨率是空间索引中的
GRIDS =(LEVEL_1 = MEDIUM,LEVEL_2 = MEDIUM,LEVEL_3 = MEDIUM,LEVEL_4 = MEDIUM)部分。该文档比我做得更好。 technet.microsoft.com/en-us/library/bb964712(v=sql.105).aspx
标签: sql-server indexing geo geography sqlperformance