2017-05-30 4 views
0

J'ai une table pour les points géocodés. Cette requête que j'optimise essaie d'extraire les points correspondants pour un emplacement lat-long. Malheureusement, c'est trop lent!Optimisation de la requête de boîte englobante

La table est essentiellement une liste de boîtes englobantes et une adresse correspondante. Il contient également un DBGeography de la boîte de délimitation exacte, mais, étant donné la lenteur de SQL, je le matérialise en .NET et y interroge DBGeography.

Ma requête cherche alors essentiellement à voir si un point est dans la boîte de délimitation [spécifié par NESW] et renvoie les résultats. Dans mon esprit, cela devrait être très rapide, mais hélas, ce n'est pas aussi rapide que je le pensais.

J'ai un index non cluster ne unique, sur les limites et l'UTC comme si

enter image description here

Notez l'UTC est nécessaire que nous revenons seulement des résultats qui ont été modifiés dans le dernier 2 semaines.

J'ai couru ce grâce à des outils de profils SQL et voici quelques informations:

  • 500k lignes dans cette table
  • La durée varie de 250-350ms par appel
  • Reads va de 5-20k

Et enfin voici la requête que j'utilise

exec sp_executesql N'SELECT 
    [Project1].[ID] AS [ID], 
    [Project1].[CENTER] AS [CENTER], 
    [Project1].[BOUNDS] AS [BOUNDS], 
    [Project1].[UTC_UPDATED] AS [UTC_UPDATED], 
    [Project1].[PLACE_ID] AS [PLACE_ID], 
    [Project1].[FORMATTED_ADDRESS] AS [FORMATTED_ADDRESS], 
    [Project1].[POST_CODE] AS [POST_CODE], 
    [Project1].[SOURCE] AS [SOURCE], 
    [Project1].[North] AS [North], 
    [Project1].[East] AS [East], 
    [Project1].[South] AS [South], 
    [Project1].[West] AS [West] 
    FROM (SELECT 
     [Extent1].[ID] AS [ID], 
     [Extent1].[CENTER] AS [CENTER], 
     [Extent1].[BOUNDS] AS [BOUNDS], 
     [Extent1].[UTC_UPDATED] AS [UTC_UPDATED], 
     [Extent1].[PLACE_ID] AS [PLACE_ID], 
     [Extent1].[FORMATTED_ADDRESS] AS [FORMATTED_ADDRESS], 
     [Extent1].[POST_CODE] AS [POST_CODE], 
     [Extent1].[SOURCE] AS [SOURCE], 
     [Extent1].[North] AS [North], 
     [Extent1].[East] AS [East], 
     [Extent1].[South] AS [South], 
     [Extent1].[West] AS [West] 
     FROM [dbo].[HST_GEOCODE_POINTS] AS [Extent1] 
     WHERE ([Extent1].[UTC_UPDATED] > @p__linq__0) AND ([Extent1].[North] >= @p__linq__1) AND ([Extent1].[East] >= @p__linq__2) AND ([Extent1].[South] <= @p__linq__3) AND ([Extent1].[West] <= @p__linq__4) 
    ) AS [Project1] 
    ORDER BY [Project1].[UTC_UPDATED] DESC, [Project1].[SOURCE] DESC',N'@p__linq__0 datetime2(7),@p__linq__1 float,@p__linq__2 float,@p__linq__3 float,@p__linq__4 float',@p__linq__0='2017-05-16 11:12:12.4425257',@p__linq__1=53.016466402998645,@p__linq__2=-1.715320912729779,@p__linq__3=53.016466402998645,@p__linq__4=-1.715320912729779 

note Mon UTC est actuellement le premier dans cette requête mais le dernier dans l'index. Ironiquement, cela semble rendre mes requêtes plus rapides bien que chaque appel touche 20k lectures.

+0

@GordonLinoff Je ne suis pas sûr de ce que vous voulez dire? J'ai déjà un DBGeography sur la table mais je ne peux pas l'utiliser pour l'interroger car c'est trop lent. – Chris

+0

Ajout d'un plan d'exécution à partir de SQL Sentry Plan Explorer (un outil gratuit)? Cela aiderait beaucoup. –

+0

Combien de lignes sont généralement mises à jour en deux semaines? Si ce n'est pas le cas, il peut être plus efficace d'avoir la colonne date dans l'index ... – user1429080

Répondre

0

1) Utilisation geography au lieu de DBGeography pour stocker des données: https://docs.microsoft.com/en-us/sql/t-sql/spatial-geography/spatial-types-geography

2) Créer un index spatial sur geography colonne https://docs.microsoft.com/en-us/sql/relational-databases/spatial/spatial-indexes-overview

3) Cherchez des lignes de lignes que vous avez besoin en utilisant la fonction your_geography.STIntersects(other_geography) ou similaire

Malheureusement, vous ne pouvez pas ajouter d'autres colonnes dans votre index spatial (UTC_UPDATED par exemple).

p.s. vous pouvez également essayer geometry type

+0

Salut, merci pour votre réponse. J'ai déjà une colonne de type geography et j'avais un index dessus mais c'était beaucoup plus lent que ma méthode actuelle. Ma méthode actuelle est en fait 50x plus rapide en fait sur le temps d'exécution et lit environ 15 fois moins de lignes – Chris

+0

50x plus rapide signifie que la requête de colonne 'geography' s'exécute 300ms * 50 = ~ 15 secondes? Êtes-vous sûr que l'index spatial a été utilisé?Combien de lignes sont filtrées par les coordonnées et combien de lignes sont filtrées par date? –

+0

Au moment où j'ai noté mes statistiques, la requête utilisant la géographie prenait 1650 ms et atteignait 319.450 lectures. Avec la requête ci-dessus, il atteignait 21 195 lectures et prenait 31 ms. Après avoir fait fonctionner le système pendant quelques jours de plus, je le vois ralentir un peu, ce qui me demande ce que je pourrais faire. Chaque ressource que je vois en ligne déclare que la géographie est intrinsèquement lente cependant? – Chris