У меня около 75 миллионов записей в базе данных SQL Server 2008 R2 Express. Каждый - это длинный лат, соответствующий некоторому значению. Таблица имеет столбец географии. Я пытаюсь найти ближайшего соседа для данной широты и долготы (точка). У меня уже есть запрос с пространственным индексом на месте. Но в зависимости от того, где запись находится в базе данных, например, в первом или последнем квартале, запрос может занять от 3 до 30 секунд, чтобы найти ближайшего соседа. Я чувствую, что это может быть оптимизировано, чтобы дать намного более быстрый результат, оптимизируя запрос или пространственный индекс. Прямо сейчас применен некоторый пространственный индекс с настройками по умолчанию. Вот как выглядит моя таблица и запрос.
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]
Пространственный индекс, который я использую:
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]
Вот запрос, который я использую:
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
Вот образец лат длинных в моей базе данных. дать представление о точности и плотности. Все 70 миллионов записей относятся к одному городу (данные Лидара).
POINT (-95.669434934023087 30.049513838913736)
Теперь этот запрос дает мне результаты, как я описал выше, но я хочу максимально повысить производительность. Я предполагаю, что путем настройки значений по умолчанию пространственного индекса я могу быть выше, чтобы лучше оптимизировать производительность. Есть какие-нибудь подсказки по этому поводу?
Я попытался изменить буфер от 10 до 1000, но с почти такими же результатами.
Также приветствуются любые другие предложения по улучшению производительности.
Вот система, которую я использую сейчас:
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
тега.Ответы:
Попробуйте запустить хранимую процедуру sp_help_spatial_geography_index, чтобы получить подробную информацию об использовании вашего пространственного индекса. Вы должны быть в состоянии использовать что-то вроде:
Опубликуйте результаты в своем вопросе, чтобы увидеть, если что-то выделяется. Значение каждого из пунктов можно найти здесь .
Если ваши координаты были спроецированы, вы также можете выполнить простой непространственный запрос для вычисленных полей X, Y и проверить X <MinX и X> MaxX и т. Д.
Проецирование ваших координат (в поле типа GEOMETRY) также позволяет вам ограничить пространственный индекс объемом данных, что может значительно повысить производительность. Замените экстенты мира экстентами ваших данных:
источник
Рассмотрим упрощение буфера с помощью BufferwithTolerance . Если точки плотно упакованы, система должна определить, находится ли точка по обе стороны от границы. Чем проще эта линия, тем меньше работы приходится выполнять машине.
источник
Посмотрите этот ресурс Исаака Кунена об использовании таблицы чисел для оптимизации ближайшего соседа с использованием пространственного индекса
http://blogs.msdn.com/b/isaac/archive/2008/10/23/nearest-neighbors.aspx
источник