4

根据 SQL Profiler,我的繁琐查询需要 3 秒才能返回,并且需要大量读取。为什么?

我有一张表,里面有 5,000,000 个账户,这些账户都是地理编码的点。所有帐户都聚集在城市 20 英里半径范围内。我的索引看起来像这样。

CREATE SPATIAL INDEX [IX_CI_Geocode] ON [dbo].[CustomerInformation] 
(
    [Geocode]
)USING  GEOGRAPHY_GRID 
WITH (
GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = LOW), 
CELLS_PER_OBJECT = 128, PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

当我运行如下简单的查询时:

DECLARE @g geography = geography::Point(41.848039, -87.96361, 4326);
DECLARE @region geography = @g.STBuffer(5000);

select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.STIntersects(@region) = 1

返回需要 3 秒,根据 SQL Server Profiler,它需要 12,203 的 CPU 和 1,218,873 的读取。这些似乎是使用索引的巨大数字。

为什么这么慢?为什么这需要从硬盘驱动器读取这么多?我能做些什么来提高这个性能?

查看查询计划,下面屏幕截图中的过滤器运算符是查询成本的 34%。

在此处输入图像描述

“Clustered Index Seek”运算符占查询的 63%。

在此处输入图像描述

4

2 回答 2

1

我最终的解决方案是改用过滤器。它会返回很多误报,但在性能方面却快了 3 倍。在我得到结果集之后,我应用一个距离函数来删除我不关心的那些,这似乎很快。

对 500 万个帐户的第一个选择查询需要 1 秒。第二个需要 3 秒。

DECLARE @g geography = geography::Point(41.848039, -87.96361, 4326);
DECLARE @region geography = @g.STBuffer(5000);

select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.Filter(@region) = 1


select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.STIntersects(@region) = 1
于 2011-08-04T20:14:14.093 回答
0

根据我的数学技能,如果您对 STBuffer() 并不真正感兴趣,则先执行 STBuffer() 感觉像是额外的工作。

您能为我尝试以下方法并报告结果吗?

DECLARE @g geography = geography::Point(41.848039, -87.96361, 4326);

select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.STDistance(@g) <= 5000

另一方面,有没有办法可以提供数据库,以便我自己测试?

于 2011-09-15T06:36:39.797 回答