3

我有一个位于 SQL Server 2008 上的数据库,其中包含约 120 亿行,所有行都包含纬度、经度和相应的地理字段。我最近需要添加对地理字段的查询功能。我添加了空间索引,处理超过 4TB 的数据需要 6 天。

CREATE SPATIAL INDEX IX_Location_Geo ON 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

使用这样的查询添加预期......

SELECT TOP 100 
    ci.LocationID, ci.Geo.STDistance(@g)  
FROM Location ci WITH(INDEX(IX_Location_Geo))
WHERE ci.Geo.Filter(@region) = 1 
ORDER BY ci.Geo.STDistance(@g)

这是估计的执行计划......

执行计划

我在 100 个轧机行的样本集上测试了这个查询,它工作得非常好。但是在 12 个账单行上,查询在约 4 小时后没有响应,最后由于磁盘写入错误而失败,这很奇怪,因为磁盘有 5TB 未使用。

Msg 1101, Level 17, State 10, Line 4 Could not allocate a new page 
for database 'TEMPDB' because of insufficient disk space in filegroup 
'DEFAULT'. Create the necessary space by dropping objects in the filegroup, 
adding additional files to the filegroup, or setting autogrowth on for 
existing files in the filegroup.

希望有人可能会看到我的明显疏忽。非常感谢!

4

2 回答 2

1

与其使用垂直可扩展性(添加更多内存、CPU、硬盘空间 - 制作一台强大的机器),不如考虑使用水平可扩展性(在许多商品服务器之间拆分负载)。任何操作都需要时间和空间。Big-O 表示法描述了,对于任何花费超过 的计算O(N),你注定要计算这样的体积。这就是为什么从高层次来看,您会遇到错误并且需要大量时间来完成查询。

可能的解决方案

改变数据访问的模式。使用分片 - 将数据拆分成更小的块。广泛使用WHERE子句和Skip/Take分页模式(我不确定 T-SQL 中的正确语法)。也Map-Reduce有引起轰动的图案。简而言之,停止以音量垂直缩放。

于 2012-10-07T19:36:59.083 回答
0

您发布的错误消息说磁盘空间已用完tempdb,而不是您的主数据库。因此,您可以为其腾出可用空间,但 SQL Server 首先应该会消耗这么多空间!所以这不是一个解决方案。

请张贴预计的执行计划(因为您无法获得实际的执行计划)。我将用我对计划的想法更新这个答案。

作为一般评论:调试查询性能问题通常从计划开始,因为它告诉您 SQL Server 在执行时做了什么。

于 2012-10-08T10:47:01.143 回答