/ / Database spaziale, comportamento strano dell'indice - tsql, sql-server-2008, spaziale, indice spaziale

Database spaziale, comportamento strano dell'indice - tsql, sql-server-2008, spaziale, indice-spaziale

Quindi, il mio database ha una tabella con un ID di tipo BigInt e una geometria di tipo Geometry. Il campo Geometria ha un indice spaziale chiamato idx_Geometry

La seguente query funziona come previsto utilizzando l'indice:

DECLARE @Geometry geometry
SET @Geometry = geometry::Parse("Polygon((300000 300000, 300000 325000, 325000 325000, 325000 300000, 300000 300000))")
SELECT Id FROM [Database].[dbo].[Table] WITH(index(idx_Geometry)) WHERE Geometry.STIntersects(@Geometry) = 1

Tuttavia, quando provo la query

DECLARE @Geometry geometry
SET @Geometry = geometry::Parse("Polygon((300000 300000, 300000 325000, 325000 325000, 325000 300000, 300000 300000))")
SELECT a.Id FROM [Database].[dbo].[Table] a with(Index(idx_Geometry)) WHERE a.Geometry.STIntersects(@Geometry) = 0

Ottengo il messaggio di errore:

Il Query Processor non è stato in grado di produrre una domandapianificare una query con a suggerimento sull'indice spaziale. Motivo: spaziale gli indici non supportano il confronto fornito nel predicato. Provare rimuovendo i suggerimenti dell'indice o rimuovendo SET FORCEPLAN.

Per quanto mi riguarda, queste due query sono sostanzialmente equivalenti. Qualcuno può spiegare perché questo sta accadendo e come (o se) posso far funzionare l'indice con la seconda query?

Grazie

Modificare: Ho appena notato che il secondo era = 0, non = 1 nella clausola where, qualcuno sa perché l'indice non può essere utilizzato con = 0? (La seconda query funziona con = 1)

Modifica 2: Solo un aggiornamento di ciò che funziona e cosa no

DECLARE @Geometry geometry
SET @Geometry = geometry::Parse("Polygon((300000 300000, 300000 325000, 325000 325000, 325000 300000, 300000 300000))")

--Works
SELECT Id FROM [RoadRoutingDatabase].[dbo].[Node] WITH(index(idx_Geometry)) WHERE Geometry.STIntersects(@Geometry) = 1
SELECT a.Id FROM [RoadRoutingDatabase].[dbo].[Node] a with(Index(idx_Geometry)) WHERE a.Geometry.STIntersects(@Geometry) = 1

--Gives Error Message
SELECT Id FROM [RoadRoutingDatabase].[dbo].[Node] WITH(index(idx_Geometry)) WHERE Geometry.STIntersects(@Geometry) = 0
SELECT a.Id FROM [RoadRoutingDatabase].[dbo].[Node] a with(Index(idx_Geometry)) WHERE a.Geometry.STIntersects(@Geometry) = 0

--Works but doesn"t use Index
SELECT Id FROM [RoadRoutingDatabase].[dbo].[Node] WHERE Geometry.STIntersects(@Geometry) = 0
SELECT a.Id FROM [RoadRoutingDatabase].[dbo].[Node] a WHERE a.Geometry.STIntersects(@Geometry) = 0

Modifica 3: Ho trovato una soluzione per il mio problema con un join sinistro e un controllo null ma sono ancora curioso del perché non è possibile utilizzare un indice su un falso incrocio se qualcuno può illuminarmi

risposte:

1 per risposta № 1

Non vi è alcun motivo tecnico l'indice spazialenon è stato in grado di supportare questa query, tuttavia il piano di query generato sarebbe essenzialmente lo stesso di farlo da solo con un anti semi join sinistro. È stato preso in considerazione il supporto di questo, ma farlo comporta ulteriori modifiche allo Strumento per ottimizzare le query al fine di abbinare questo predicato e generare il piano di query corretto.

Quindi, dato che questa non è una forma di query comune ed è ancora relativamente facile scrivere la query per utilizzare l'indice da soli, questo modello non è stato incluso nel elenco di predicati supportati per indici spaziali.