Eu tenho cerca de 75 milhões de registros em um banco de dados do SQL Server 2008 R2 Express. Cada um é um lat long correspondente a algum valor. A tabela possui coluna de geografia. Estou tentando encontrar um vizinho mais próximo para uma determinada longitude de latitude (ponto). Eu já tenho uma consulta com índice espacial em vigor. Mas, dependendo de onde o registro está no banco de dados, digamos o primeiro ou o último trimestre, a consulta pode levar de 3 a 30 segundos para encontrar o vizinho mais próximo. Eu sinto que isso pode ser otimizado para gerar resultados muito mais rápidos, otimizando a consulta ou o índice espacial. No momento, aplicamos alguns índices espaciais com as configurações padrão. Aqui está a aparência da minha tabela e consulta.
CREATE TABLE lidar(
[id] [bigint] IDENTITY(1,1) NOT NULL,
[POINTID] [int] NOT NULL,
[GRID_CODE] [numeric](17, 8) NULL,
[geom] [geography] NULL,
CONSTRAINT [PK_lidar_1] PRIMARY KEY CLUSTERED ([id] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
O índice espacial que estou usando:
CREATE SPATIAL INDEX [SPATIAL_lidar] ON [dbo].[lidar] ([geom]) 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]
Aqui está a consulta que estou usando:
declare @ms_at geography = 'POINT (-95.66 30.04)';
select TOP(1) nearPoints.geom.STAsText()as latlon
from
(
select r.geom
from lidar r With(Index(SPATIAL_lidar))
where r.geom.STIntersects(@ms_at.STBuffer(1000)) = 1
) nearPoints
Aqui está um exemplo de long long no meu banco de dados. para dar uma idéia de precisão e densidade. Todos os 70 milhões de registros são para uma cidade (dados Lidar).
POINT (-95.669434934023087 30.049513838913736)
Agora, essa consulta me fornece resultados como descrevi acima, mas quero melhorar o desempenho o máximo possível. Meu palpite é ajustar os valores padrão do índice espacial em que posso estar acima para otimizar melhor o desempenho. Alguma pista sobre isso?
Tentei variar o buffer de 10 para 1000, mas com quase os mesmos resultados.
Também são bem-vindas quaisquer outras sugestões para melhorar o desempenho.
Aqui está o sistema que estou usando agora:
Windows 7 64bit Professional
Intel(R) Core(TM)2 Quad CPU Q9650 @ 3.00GHz (4 CPUs), ~3.0GHz
Ram: 8 GB
NVIDIA GeForce 9500 GT
lidar
tag.Respostas:
Tente executar o procedimento armazenado sp_help_spatial_geography_index para obter detalhes de como seu índice espacial está sendo usado. Você deve poder usar algo como:
Poste os resultados em sua pergunta para ver se algo se destaca. O significado para cada um dos itens pode ser encontrado aqui .
Se suas coordenadas foram projetadas, você também pode fazer uma consulta não espacial simples nos campos X, Y calculados e verificar X <MinX e X> MaxX etc.
Projetar suas coordenadas (em um campo do tipo GEOMETRIA) também permite limitar seu índice espacial à extensão dos dados, o que pode acelerar consideravelmente o desempenho. Substitua as extensões mundiais pelas extensões de seus dados:
fonte
Considere simplificar o buffer com BufferwithTolerance . Se os pontos estão bem compactados, o sistema precisa identificar se um ponto está em ambos os lados do limite. Quanto mais simples a linha, menos trabalho a máquina precisa fazer.
fonte
Confira este recurso de Isaac Kunen sobre o uso de uma tabela de números para otimizar o vizinho mais próximo usando um índice espacial
http://blogs.msdn.com/b/isaac/archive/2008/10/23/nearest-neighbors.aspx
fonte