Thanks for the reply. I realise the last query does not use the index, I don't understand why though. Here's the execution plan for the first select query: |--Compute Scalar(DEFINE:([Expr1002]=[@Point].STDistance([tempdb].[dbo].[#SomePoints].[Point] as [S].[Point])*(1.000000000000000e-003))) |--Nested Loops(Inner Join, OUTER REFERENCES:([S].[Point], [Expr1004], [Expr1005], [Expr1006])) |--Nested Loops(Inner Join, OUTER REFERENCES:([tempdb].[sys].[extended_index_1557580587_384000].[pk0], [Expr1064]) WITH UNORDERED PREFETCH) | |--Hash Match(Aggregate, HASH:([tempdb].[sys].[extended_index_1557580587_384000].[pk0]) DEFINE:([Expr1004]=MAX([Expr1057]), [Expr1005]=ANY([tempdb].[sys].[extended_index_1557580587_384000].[SRID]), [Expr1006]=ANY([Expr1058]))) | | |--Compute Scalar(DEFINE:([Expr1057]=[tempdb].[sys].[extended_index_1557580587_384000].[Cell_Attributes]+[Expr1052], [Expr1058]=[Expr1053])) | | |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1054], [Expr1055], [Expr1063]) WITH UNORDERED PREFETCH) | | |--Hash Match(Aggregate, HASH:([Expr1054], [Expr1055]), RESIDUAL:([Expr1054] = [Expr1054] AND [Expr1055] = [Expr1055]) DEFINE:([Expr1052]=MAX([Expr1056]), [Expr1053]=ANY([SRID]))) | | | |--Nested Loops(Inner Join, OUTER REFERENCES:([Cell_Id], [Cell_Attributes])) | | | |--Table-valued function | | | |--Constant Scan(VALUES:(([Cell_Id],getdescendantlimitforspatialbinary([Cell_Id]),CASE WHEN (2)=[Cell_Attributes] THEN (2) ELSE (0) END),([Cell_Id],[Cell_Id],[Cell_Attributes]),(getancestorforspatialbinary([Cell_Id | | |--Clustered Index Seek(OBJECT:([tempdb].[sys].[extended_index_1557580587_384000].[tempindex]), SEEK:([tempdb].[sys].[extended_index_1557580587_384000].[Cell_Id] >= [Expr1054] AND [tempdb].[sys].[extended_index_1557580587_38 | |--Clustered Index Seek(OBJECT:([tempdb].[dbo].[#SomePoints] AS [S]), SEEK:([S].[Id]=[tempdb].[sys].[extended_index_1557580587_384000].[pk0]) ORDERED FORWARD) |--Filter(WHERE:(STARTUP EXPR(CASE WHEN [Expr1004]>(2) THEN CASE WHEN [Expr1005]=[Expr1006] THEN (1) ELSE (0) END ELSE [tempdb].[dbo].[#SomePoints].[Point] as [S].[Point].STDistance([@Point])<(7.000000000000000e+006) END=(1)))) |--Constant Scan
And here's for the last, showing no use of the spatial index: |--Compute Scalar(DEFINE:([Expr1003]=[@Point].STDistance([tempdb].[dbo].[#SomePoints].[Point] as [S].[Point])*(1.000000000000000e-003))) |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[#SomePoints] AS [S]))
This query shows what I would like to do, a nearest neighbour calculation for many points:--does not use spatial index (why not?)SELECT S1.Id, ClosestDistance=min(S2.Point.STDistance (S1.Point))*1e-3 --distance in KMFROM #SomePoints S1 --WITH(INDEX(tempindex)) --throws up error with hint CROSS JOIN #SomePoints S2GROUP BY S1.Id
It also does not use the indexes like the ORDER BY query shown earlier. Here's the execution plan: |--Compute Scalar(DEFINE:([Expr1005]=[Expr1004]*(1.000000000000000e-003))) |--Parallelism(Gather Streams) |--Stream Aggregate(GROUP BY:([S1].[Id]) DEFINE:([Expr1004]=MIN([partialagg1006]))) |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([S1].[Id]), ORDER BY:([S1].[Id] ASC)) |--Stream Aggregate(GROUP BY:([S1].[Id]) DEFINE:([partialagg1006]=MIN([tempdb].[dbo].[#SomePoints].[Point] as [S2].[Point].STDistance([tempdb].[dbo].[#SomePoints].[Point] as [S1].[Point])))) |--Nested Loops(Inner Join) |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[#SomePoints] AS [S1]), ORDERED FORWARD) |--Table Spool |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[#SomePoints] AS [S2]))
Is this a bug in SQL Server 2008? Does anyone know if Microsoft plan to address this? I've looked into how spatial indexes in SQL Server work (see [url]http://technet.microsoft.com/en-us/library/bb964712.aspx[/url]) and it seems they should definitely help with this kind of query. Maybe there's some complexity here I don't understand. If anyone can explain this to me I'd be extremely grateful.Thanks