J'ai environ 75 millions d'enregistrements dans une base de données SQL Server 2008 R2 Express. Chacun est un lat long correspondant à une certaine valeur. Le tableau a une colonne géographique. J'essaie de trouver un voisin le plus proche pour une longitude (point) de latitude donnée. J'ai déjà une requête avec index spatial en place. Mais selon l'endroit où l'enregistrement se trouve dans la base de données, par exemple au premier trimestre ou au dernier trimestre, la requête peut prendre environ 3 à 30 secondes pour trouver le voisin le plus proche. Je pense que cela peut être optimisé pour donner un résultat beaucoup plus rapide en optimisant la requête ou l'index spatial. À l'heure actuelle appliqué certains index spatial avec les paramètres par défaut. Voici à quoi ressemble ma table et ma requête.
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]
L'index spatial que j'utilise:
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]
Voici la requête que j'utilise:
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
Voici un échantillon de lat longs dans ma base de données. pour donner une idée de la précision et de la densité. Tous les 70 millions d'enregistrements concernent une seule ville (données Lidar).
POINT (-95.669434934023087 30.049513838913736)
Maintenant, cette requête me donne des résultats comme je l'ai décrit ci-dessus, mais je veux améliorer les performances autant que possible. Je suppose qu'en ajustant les valeurs par défaut de l'indice spatial, je peux être au-dessus pour mieux optimiser les performances. Des indices à ce sujet?
J'ai essayé de faire varier le tampon de 10 à 1000 mais avec presque les mêmes résultats.
Toutes autres suggestions pour améliorer les performances sont également les bienvenues.
Voici le système que j'utilise actuellement:
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
balise.Réponses:
Essayez d'exécuter la procédure stockée sp_help_spatial_geography_index pour obtenir des détails sur la façon dont votre index spatial est utilisé. Vous devriez pouvoir utiliser quelque chose comme:
Affichez les résultats dans votre question pour voir si quelque chose se démarque. La signification de chacun des éléments peut être trouvée ici .
Si vos coordonnées ont été projetées, vous pouvez également effectuer une simple requête non spatiale sur les champs X, Y calculés et vérifier X <MinX et X> MaxX, etc.
La projection de vos coordonnées (dans un champ de type GÉOMÉTRIE) vous permet également de limiter votre index spatial à l'étendue des données ce qui peut accélérer considérablement les performances. Remplacez l'étendue mondiale par l'étendue de vos données:
la source
Envisagez de simplifier le tampon avec BufferwithTolerance . Si les points sont serrés, le système doit identifier si un point se trouve de part et d'autre de la frontière. Plus cette ligne est simple, moins la machine doit faire de travail.
la source
Consultez cette ressource d'Isaac Kunen sur l'utilisation d'une table de nombres pour optimiser le plus proche voisin à l'aide d'un index spatial
http://blogs.msdn.com/b/isaac/archive/2008/10/23/nearest-neighbors.aspx
la source