Quantcast
Channel: SQL Server Spatial forum
Viewing all 364 articles
Browse latest View live

Insert using Spatial Index fails when called from PHP

$
0
0

I have a stored procedure that inserts into a table with a spatial index on one of its fields.

When I run the procedure from SQL Server Management Studio it runs just fine.

When I run it from PHP, it returns the error: "INSERT failed because the following SET options have incorrect settings: 'CONCAT_NULL_YIELDS_NULL, ANSI_WARNINGS, ANSI_PADDING'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations"

From within Management Studio, I have tried many different combinations of settings, until I wound up with the list I have in the procedure below.

Within Managment Studio the error changes based on the options I have set, but PHP always replies with: 'CONCAT_NULL_YIELDS_NULL, ANSI_WARNINGS, ANSI_PADDING'

I have configured PHP to use the same SQL user as management studio, and I have tried both mssql_query and mssql_execute with bound parameters.

The spatial index is on the field post.location If I remove the spatial index it works, but I need the spatial index.

CREATE PROCEDURE insert_post ( @subject AS VARCHAR(250), @body AS VARCHAR(2000), @latitude AS FLOAT, @longitude AS FLOAT ) AS BEGIN

SET NOCOUNT ON

SET ANSI_WARNINGS ON
SET ANSI_PADDING ON
SET CONCAT_NULL_YIELDS_NULL ON
SET NUMERIC_ROUNDABORT OFF

DECLARE @location AS geography = geography::Point(@latitude, @longitude, 4326)

INSERT INTO post
(
    subject,
    body,
    location
) VALUES (
    @subject,
    @body,
    @location
)

END


Is there a way to apply a precise value of how round the STBuffer() applies to a geography?

$
0
0

Hello,

I am attempting to work on moving my data into SQL Server spatial geography. I have a valid geography and am able to apply a buffer of (150 feet or 0.3048 meters) as shown below.  

My question is there a way to apply a precision to how smooth the buffer is made ? I currently have MapInfo software and it allows me to apply "25 segments per circle" where the 25 can be whatever I choose (buffer is the red ring shown below which appears not as wide as the SQL server buffer above)  Please ignore the cropped portion of the red-line below; however, I was just trying to give a visual of what the buffer looks like now in my MapInfo format...

Is this possible with SQL Server Spatial?  

Thanks in advance.
Nick


Select on table with 1800 rows is slow

$
0
0

I have a table with 1800 rows. Each entry has a geometry position and a geometry polygon around the position. I am using the polygon to detect which (other) entries are near the current entry.

In the following testdata and the subsequent query, i am filtering on 625 (of 1865) rows, and then using the .STContains-method to finding other rows (the testdata is fully found by this query, in the live database the values are not so regular as in the testdata.

The query take 6500 ms. In the live database, only 800 records are (yet) in the table, and it takes 2200 ms. 

select SlowQueryTable.id
from SlowQueryTable
inner join dbo.SlowQueryTable as SlowQueryTableSeen
    on SlowQueryTable.[box].STContains(SlowQueryTableSeen.position) = 1
where   SlowQueryTable.userId = 2   

(The query in the live system is even more complex, but this is main part of it and even simplified as it is just takes too long).

This script generates test data and runs the query:

-- The number table is just needed to generate test data
CREATE TABLE [dbo].[numbers](
    [number] [int] NOT NULL
)
go
declare @t table (number int)
insert into @t  select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9

insert into numbers
    select * from
    (
        select
            t1.number + t2.number*10 + t3.number*100 + t4.number*1000 as x
        from
            @t as t1,
            @t as t2,
            @t as t3,
            @t as t4
    ) as  t1
    order by x
go


-- this is the table which has the slow query. The Columns [userId], [position] and [box] are the relevant ones
CREATE TABLE [dbo].SlowQueryTable(
    [id] [int] IDENTITY(1,1) NOT NULL,
    [userId] [int] NOT NULL,
    [position] [geometry] NOT NULL,
    [box] [geometry] NULL,
    constraint SlowQueryTable_primary primary key clustered (id)
);
create nonclustered index SlowQueryTable_UserIdKey on [dbo].SlowQueryTable(userId);

--insert testdata: three users with each 625 entries. Each entry per user has its unique position, and a rectangle (box) around it.
-- In the database in question, the positions are a bit more random, often tens of entries have the same position. The slow query is nevertheless visible with these testdata
declare @range int;
set @range = 5;
INSERT INTO [dbo].SlowQueryTable (userId,position,box)
select
    users.number,
    geometry::STGeomFromText('POINT (' + convert(varchar(15), X) + ' ' + convert(varchar(15), Y) + ')',0),
    geometry::STPolyFromText('POLYGON ((' + convert(varchar(15), X - @range) + ' ' + convert(varchar(15), Y - @range) + ', '+ convert(varchar(15), X + @range) + ' ' + convert(varchar(15), Y - @range) + ', '+ convert(varchar(15), X + @range) + ' ' + convert(varchar(15), Y + @range) + ', '+ convert(varchar(15), X - @range) + ' ' + convert(varchar(15), Y + @range) + ','+ convert(varchar(15), X - @range) + ' ' + convert(varchar(15), Y - @range) + '))', 0)
from (
select
    (numberX.number * 40) + 4520 as X
,(numberY.number * 40) + 4520 as Y
from numbers  as numberX
cross apply numbers  as numberY
where numberX.number < (1000 / 40)
and numberY.number < (1000 / 40)) as positions
cross apply numbers  as users
where users.number < 3


CREATE SPATIAL INDEX [SlowQueryTable_position]
   ON [dbo].SlowQueryTable([position])
   USING GEOMETRY_GRID
   WITH (
   BOUNDING_BOX = ( 4500, 4500, 5500, 5500 ),
   GRIDS =(LEVEL_1 =   HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH),
   CELLS_PER_OBJECT = 64, PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF,   ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
go
ALTER INDEX [SlowQueryTable_position] ON [dbo].SlowQueryTable
REBUILD;
go

CREATE SPATIAL INDEX [SlowQueryTable_box]
   ON [dbo].SlowQueryTable(box)
   USING GEOMETRY_GRID
   WITH ( BOUNDING_BOX = ( 4500, 4500, 5500, 5500 ) ,
   GRIDS =(LEVEL_1 =   HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH),
   CELLS_PER_OBJECT = 64, PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF,   ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
go
ALTER INDEX [SlowQueryTable_box] ON [dbo].SlowQueryTable
REBUILD;
go


SET STATISTICS IO ON
SET STATSTICS TIME ON




-- this is finally the query. it takes about 6500 ms
select SlowQueryTable.id
    into #t1
    from SlowQueryTable
    inner join dbo.SlowQueryTable as SlowQueryTableSeen
        on SlowQueryTable.[box].STContains(SlowQueryTableSeen.position) = 1
        --on SlowQueryTable.position.STDistance(SlowQueryTableSeen.position) < 5
    where   SlowQueryTable.userId = 2



drop table #t1
drop table SlowQueryTable
drop table numbers

Using an explicit index hint does do the job, but then the query gets slow if i change the where clause:

select SlowQueryTable.id
    into #t1
    from SlowQueryTable
    with (index([SlowQueryTable_box]))
    inner join dbo.SlowQueryTable as SlowQueryTableSeen
        on SlowQueryTable.[box].STContains(SlowQueryTableSeen.position) = 1
    where   SlowQueryTable.userId = 2   

leads to 600ms, and changing the where clause

where   SlowQueryTable.id = 100

slows it again down to 1200ms.  Filtering on ID get massively slowed down when using index hint on the spatial index.

Since the table in the live system will grow to 10000+ rows, and the query is called often by users, I badly need a more efficient query.

Do I have to create a different queries for each use-case, some with index hints and some without?



stored procedure - Help

$
0
0
USE [TyreSannerSQL]
GO
/****** Object:  StoredProcedure [dbo].[AddCustomerDetails]    Script Date: 10/10/2014 16:12:02 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[AddCustomerDetails]

/***********************Declare variables ***********************/

/******tblCustomer******/
@Forename nvarchar(50), 
@Surname nvarchar(50),
@HouseNo  nvarchar(50),
@CustAddress nvarchar(50),
@Town nvarchar(50),
@Postcode nvarchar(50),
@ContactNo nvarchar(50),
@EmailAddress nvarchar(50),

/******tblOrder******/
@AnyAdditionalInfo nvarchar(Max)

/******tblLink_OrderProduct******/
@ProductQuantity int, 
@TotalProductSaleCost decimal,
@FittingDate date,
@FittingTime Time,
@Terms bit,

As
DECLARE @CustomerFK TABLE (ID uniqueidentifier);
DECLARE @OrderFK TABLE (ID uniqueidentifier);
Begin TRANSACTION
SET NOCOUNT ON 

INSERT INTO [TyreSannerSQL].[dbo].[Customer](Forename, Surname, HouseNo, CustAddress, Town, Postcode, ContactNo, EmailAddress)
 
OUTPUT INSERTED.CustomerID INTO @CustomerFK
 
 
 VALUES      
  (@Forename,                 
   @Surname,
   @HouseNo,
   @CustAddress,
   @Town,
   @Postcode,
   @ContactNo,
   @EmailAddress)
  
   
  INSERT INTO [TyreSannerSQL].[dbo].[Order]
  
(CustomerFK, 
AnyAdditionalInfo)

 VALUES 
((SELECT ID FROM @CustomerFK),
@AnyAdditionalInfo)
 
 
INSERT INTO [TyreSannerSQL].[dbo].[Link_OrderProduct]
     OUTPUT INSERTED.OrderID INTO @OrderFK
    
(OrderFK, 
ProductQuantity,
TotalProductSaleCost,
FittingDate,
FittingTime,
Terms)
 

 VALUES 
((SELECT ID FROM @OrderFK),
@ProductQuantity,
@TotalProductSaleCost,
@FittingDate,
@FittingTime,
@Terms)
 
 
   
COMMIT TRANSACTION


Triangulation of a position from three known points

$
0
0

Let's say I have three records in a database table with a known location in a geography column.

For ease of explanation let's say they're Houston, Seattle and New York.

Within the table is a field which has an integer distance value and the distance is miles from, say, Las Vegas.

Las Vegas isn't a known point in the database.  Is there a way I can triangulate the coordinate of Las Vegas from the three known coordinates and their distance values?

Triangulation of a position from three known points

$
0
0

Let's say I have three records in a database table with a known location in a geography column.

For ease of explanation let's say they're Houston, Seattle and New York.

Within the table is a field which has an integer distance value and the distance is miles from, say, Las Vegas.

Las Vegas isn't a known point in the database.  Is there a way I can triangulate the coordinate of Las Vegas from the three known coordinates and their distance values?

int or uniqueidentifier

$
0
0

Hi folks, what is the best format to use for your primary key and foreign key?

 I have Google it, it seems int is the preferred choice, would anyone disagree with this?

Brucey

Stored Proc

$
0
0

Hi folks, can’t seem to solve this one, I keep getting error message;

Msg 207, Level 16, State 1, Procedure AddCustomerDetails, Line 59

Invalid column name 'OrderID'.

The following code comes up with the red underline, I have tried moving the block of code but no joy!

OUTPUT INSERTED.OrderIDINTO @OrderFK

Brucey

SET ANSI_NULLS ON
 GO
 SET QUOTED_IDENTIFIER ON
 GO

ALTER PROCEDURE [dbo].[AddCustomerDetails]

/***********************Declare variables ***********************/

/******tblCustomer******/
 @Forename nvarchar(50),
 @Surname nvarchar(50),
 @HouseNo  nvarchar(50),
 @CustAddress nvarchar(50),
 @Town nvarchar(50),
 @Postcode nvarchar(50),
 @ContactNo nvarchar(50),
 @EmailAddress nvarchar(50),

/******tblOrder******/
 @AnyAdditionalInfo nvarchar(Max),

/******tblLink_OrderProduct******/
 @ProductQuantity int,
 @TotalProductSaleCost decimal,
 @FittingDate date,
 @FittingTime Time,
 @Terms bit

As
 DECLARE @CustomerFK TABLE (ID uniqueidentifier);
 DECLARE @OrderFK TABLE (ID uniqueidentifier);
 Begin TRANSACTION
 SET NOCOUNT ON

INSERT INTO [TyreSannerSQL].[dbo].[Customer](Forename, Surname, HouseNo, CustAddress, Town, Postcode, ContactNo, EmailAddress)

 OUTPUT INSERTED.CustomerID INTO @CustomerFK



  VALUES
   (@Forename,
    @Surname,
    @HouseNo,
    @CustAddress,
    @Town,
    @Postcode,
    @ContactNo,
    @EmailAddress)


   INSERT INTO [TyreSannerSQL].[dbo].[Order]


 (CustomerFK,
 AnyAdditionalInfo)

 VALUES
 ((SELECT ID FROM @CustomerFK), @AnyAdditionalInfo)


 INSERT INTO [TyreSannerSQL].[dbo].[Link_OrderProduct](OrderFK, ProductQuantity, TotalProductSaleCost, FittingDate, FittingTime, Terms)

 OUTPUT INSERTED.OrderID INTO @OrderFK

 VALUES
 ((SELECT ID FROM @OrderFK),
 @ProductQuantity,
 @TotalProductSaleCost,
 @FittingDate,
 @FittingTime,
 @Terms)


 COMMIT TRANSACTION


Latitude values must be between -90 and 90 degrees.

$
0
0

 I just have a geometry column and I use below query to convert it to geography

DECLARE @gm AS Geometry;
DECLARE @gg AS Geography;
SELECT  @gm = geometry::STGeomFromText(Cast(Spatial.dbo.MyTable.geom as nvarchar(Max)), 0) 
FROM [Spatial].[dbo].[MyTable] where ID=1

SET @gg = geography::STGeomFromText(@gm.ToString(), 4326);

I am getting below error with this query

Msg 6522, Level 16, State 1, Line 1
A .NET Framework error occurred during execution of user-defined routine or aggregate "geography": 
System.FormatException: 24201: Latitude values must be between -90 and 90 degrees.

What could I be doing wrong? Could it be that theshapefiles i have used be wrong. Is there any way to make this work?? The shapefile while I have downloaded says:- 

The projected coordinate system for the data is 
State Plane of South Texas (Zone 4204) and Datum NAD 1983.

A single cell in my geom column looks like this


SQL Server Spatial

$
0
0

Hi All,

When i am trying to get Spacial result as geography i am getting error, but its working asgeometry.

select geography::STPolyFromText(N'POLYGON ((25.264878957718125 55.39986419782508,25.245317016893644 55.394542695139535,25.225441343903093 55.39934921369422,25.209134655289827 55.39110946760047,25.20230072651774 55.41634369001258,25.25960064916269 55.42561340436805,25.264878957718125 55.39986419782508))', 4326)

This is the error while executing above query

A .NET Framework error occurred during execution of user-defined routine or aggregate "geography":
System.ArgumentException: 24200: The specified input does not represent a valid geography instance.

why its getting error as geography? . its drawing a correct polygon in map. please help me...

Thanks in advance,

Shihab.

Quering and Aggregating Geography Point Data

$
0
0
Hi All, I have a table structure like this:

CREATE TABLE [LocationStats](
[LocationStats] [int] IDENTITY(1,1) NOT NULL,
[Point] [geography] NOT NULL,
[Crossing] [bigint] NOT NULL,
[Entrances] [bigint] NOT NULL,
[Exits] [bigint] NOT NULL)

The table is loaded with data where the point derived from lat long coordinates.

I would like to query this table and aggregate the data in it, however I'd like to be able to indcate the scale of aggregation. Let me try to explain by way of an example:

If I collect say 200000 records of data for an 100sq km area, and I'm showing those points on a map scaled out to show all of it - I don't want 200000 rows of data to plot the map in my client. I would want the data aggregated at say, every 10sq km - so assuming there was a data for each of the 10sq km areas I would get 100 results back with the Crossing, Entrances, Exists summed up.

However, if we were then to zoom into to show a specific 10sq km area, I would want to firstly filter down to the displayed area and then aggregate at the 1sq km level and a more granular aggregation.

Is this possible straight out of SQL? I'm running 2012 Enterprise.

Thanks

"Look, we've all had a drink"

Widely varying response time on spatial query

$
0
0

Hi,

I have a spatial query looking like this...

   select @account_cluster_id = b.account_cluster_id
         ,@cluster_geog = b.cluster_geog
     from util.AccountCluster b with (index(SPATIAL_AccountCluster_BufferedCentroid), readpast)
          join
          util.EventGeography a with (readpast)
             on a.Account = b.Account
                and (
                        a.event_geog.STIntersects(b.buffered_centroid_geog) = 1
--or a.event_geog.STIntersects(b.cluster_geog) = 1 ) where a.ID = @id and a.invalid_geog is null -- (i.e. not invalid) ;

DDL is as follows...

CREATE TABLE [util].[AccountCluster]( [account_cluster_id] [int] NOT NULL, [Account] [int] NOT NULL, [buffered_centroid_geog] [geography] NOT NULL,
[cluster_geog] geography not null, CONSTRAINT [PK_AccountCluster] PRIMARY KEY CLUSTERED ([account_cluster_id] ASC));


... and ....

CREATE TABLE [util].[EventGeography](
	[ID] [int] NOT NULL,
	[event_geog] [geography] NULL,
	[account_cluster_id] [int] NULL,
 CONSTRAINT [PK_LiftGeography] PRIMARY KEY CLUSTERED ([ID] ASC)
);
CREATE SPATIAL INDEX [SPATIAL_AccountCluster_BufferedCentroid] ON [util].[AccountCluster]
(
	[buffered_centroid_geog]
) USING  GEOGRAPHY_AUTO_GRID
WITH (
CELLS_PER_OBJECT = 16, PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)

It is part of a procedure that loops through events and check to see if the event is in an account cluster or not. If not, create a new cluster equal to the centroid buffer (which happens to be 100m radius) else update the cluster. It takes about 8 minutes to loop through ~50 events. SOme are really fast (sub-second). Others up to 1 minutes. The events that take 1 minute in the procedure loop take sub-second time when I run the same query in isolation.

At the moment, there is only one row in the AccountCluster table. There are approx 1 million in the EventGeography but the @ID restricts this to less that 100 rows at a time.

I have a second OR predicate in the where clause but that is commented out at the moment. The Events are all in the vicinity of the cluster. The cluster is updated to incorporate the new point each loop. All these operations are sub-second.

Could somebody throw some light on this please.

Regards

Liam

How can i store latitude and longitude (of registered user locations) in sql server and how can i query it for finding locations inside X radius from point y (or any user)?

$
0
0

Hello

In my app (WP 8.1) i have to store user location (lat,lon) in sql db so how can i store that location detail? And i also have to find all the location which are inside certain radius X from another user location, How can i do this?

Any Sample project or code or any blog post?

P.S. I use sql server 2012.



SQL Server Express Performance Limitations With OGC Methods on Geometry Instances

$
0
0

I will front load my question.  Specifically, I am wondering if any of the feature restrictions with SQL Server Express cause performance limitations/reductions with OGC methods on geometry instances, e.g., STIntersects?  I have spent time reading various documents about the different editions of SQL Server, including the Features Supported by the Editions of SQL Server 2014, but nothing is jumping out at me.  The limited information on spatial features in the aforementioned document implies spatial is the same across all editions.  I am hoping this is wrong.

The situation....  I have roughly 200,000 tax parcels within 175 taxing districts.  As part of a consistency check between what is stored in tax records for taxing district and what is identified spatially, I set up a basic point-in-polygon query to identify the taxing district spatially and then count the number of parcels within in taxing district.  Surprisingly, the query took 66 minutes to run.  As I pointed out, this is being run on a test machine with SQL Server Express.

Some specifics....  I wrote the query a few different ways and compared the execution plans, and the optimizer always choose the same plan, which is good I guess since it means it is doing its job.  The execution plans show a 'Clustered Index Seek (Spatial)' being used and only costing 1%.  Coming in at 75% cost is a Filter, which appears to be connected to the STIntersects predicate.  I brute forced alternate execution plans using HINTS, but they only turned out worse, which I guess is also good since it means the optimizer did choose a good plan.  I experimented some with changing the spatial index parameters, but the impact of the options I tried was never that much.  I ended up going with "Geometry Auto Grid" with 16 cells per object.

So, why do I think 66 minutes is excessive?  The reason is that I loaded the same data sets into PostgreSQL/PostGIS, used a default spatial index, and the same query ran in 5 minutes.  Same machine, same data, SQL Server Express is 13x slower than PostgreSQL.  That is why I think 66 minutes is excessive.

Our organization is mostly an Oracle and SQL Server shop.  Since more of my background and experience are with MS databases, I prefer to work with SQL Server.  I really do want to understand what is happening here.  Is there something I can do different to get more performance out of SQL Server?  Does spatial run slower on Express versus Standard or Enterprise?  Given I did so little tuning in PostgreSQL, I still can't understand the results I am seeing.

I may or may not be able to strip the data down enough to be able to send it to someone.

How to query geography data type?

$
0
0

Hello

In my db i create table having geography type column and insert location detail (lat & lon) using point method. How can i do query for getting that location in my console application?

and also i try this got an error?



Nearest Neighbor Query takes 7 minutes

$
0
0

Hello there, First time poster on the forums. 

I've been looking into spatial comparison recently and have come across a few problems. The query I run takes 7 minutes to return the nearest neighbor. 

My table that has the Geographical locations is of the following structure and has 1.7 million rows. 

CREATE TABLE [dbo].[PostCodeData](
	[OutwardCode] [varchar](4) NOT NULL,
	[InwardCode] [varchar](3) NOT NULL,
	[Longitude] [float] NULL,
	[Latitude] [float] NULL,
	[GeoLocation] [geography] NULL,
 CONSTRAINT [PK_PostCodeData] PRIMARY KEY CLUSTERED
(
	[OutwardCode] ASC,
	[InwardCode] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]


I have another table with many records on which I only have a Geography point (which I call Geolocation) and I'm trying to get the postcode from the PostCodeData table based on the nearest [GeoLocation] naturally.

This is my query at the moment :

SELECT top 2 [PostCode]
      ,[Geolocation]
      , (select top 1 pc.InwardCode from PostCodeData pc order by pc.GeoLocation.STDistance(bg.Geolocation)) found_post_code
  FROM [tbl_potatoes] bg
  where bg.Geolocation is not null

This query is taking 7 minutes and as you can see I'm only doing this for 2 (top 2) records from the burning_glass table. What would happen if I wanted to process the whole table which has like 700k rows.

What I've tried: 

1. Created a spatial index.

2. Followed a post somewhere on these forums about applying it as a hint (WITH: WITH (INDEX(ixs_postcode)))

It didn't let me apply the hint and gave the following error : 

Query processor could not produce a query plan because of the hints defined in this query. Resubmit the query without specifying any hints and without using SET FORCEPLAN.
Any help is appreciated. 



Problem with STIntersects in SQL Server 2008R2

$
0
0

Have draw a circle in google map with 1KM radius, when i checking one latitude and longitude from out side of my circle with STIntersects function its return 1.

I am using SQL Server 2008R2 .

select geography::STGeomFromText('POINT (25.252606 55.283896)',4326)--This is a point from out side my circle area.
select geography::STGeomFromText( 'POINT(25.24096464 55.28498358)',4326).STBuffer(1000) --this is my circle with 1 KM

below my spacial result.

Thank you..

Shihab


Spatial Query, Use Multiple Cores

$
0
0

Basic question, is SQL 2012 running on Windows 2008 R2 64 bit expected to use multiple cores to execute it's tasks?

I have a table of points, 480, that has 3 empty columns that are being updated from 3 separate tables of polygons via a spatial join based on an intersection (STIntersects) of the point and polygons. All of the data is in 4326 and all tables have spatial indexes.

The server running this query has 32 logical cores, but only 1 core is used and it is maxed out. It takes 53 seconds to complete the update. I have over a million points that need this done. I want to assume that if SQL can access more cores it will complete faster.

I've looked at the actual execution plan and there is a 99% cost on the spatial query.

update A
set CONGRESS_DISTRICT = B.DISTRICT, HOUSE_DISTRICT = C.DISTRICT, SENATE_DISTRICT = D.DISTRICT
from [LegislativeMapData2014].[dbo].[CNRM_INFORCE_EXTRACT093014_COMBINED_GEOCODED] A
inner join [LegislativeMapData2014].[dbo].[CONGRESS_2014] B
on A.FEATURE_SHAPE.STIntersects(B.FEATURE_SHAPE) = 1
inner join [LegislativeMapData2014].[dbo].[HOUSE_2014] C
on A.FEATURE_SHAPE.STIntersects(C.FEATURE_SHAPE) = 1
inner join [LegislativeMapData2014].[dbo].[SENATE_2014] D
on A.FEATURE_SHAPE.STIntersects(D.FEATURE_SHAPE) = 1

Is there anything I can do to improve the performance of the query? Do I need to hint the indexes? Or something else?

Thanks



Will the "real" Nearest Neighbor please stand up!

$
0
0

I have a table of 16,000 points and a table of 51 polygons. Simply I need to join a value from each polygon nearest each point to that point. I'm running SQL 2012. I can't set a max search distance, so it seems my only option is to brute force it by distancing each polygon from each point and ranking. It takes a while for obvious reasons.

Is there actually a nearest neighbor method, or just hairy queries that result in the same?

Is there a better way than what I have done?

SELECT RISKID, RETURN_VAL
FROM
	(
	SELECT RISKID, RETURN_VAL, RANK() OVER(PARTITION BY RISKID ORDER BY DISTANCE ASC) AS [RANK]
	FROM
		(
		SELECT A.RISKID, B.RETURN_VAL, A.FEATURE_SHAPE.STDistance(B.FEATURE_SHAPE) AS DISTANCE, A.P_KEY
		FROM [AD_HOC].[DBO].[POINTS] A
		CROSS JOIN [SPATIAL_DATA].[DBO].[POLYGONS] B
		WHERE A.RESULT_CODE <> 'N' and A.WIND_TERRITORY IS NULL
		) X
	) Y
WHERE [RANK] = 1

Thanks

Simple count of points within a radius takes too long

$
0
0

I have reduced my table to just two columns - an ID and a Geography column. I have a spatial index on the latter and a clustered PK index on the former. There are 10m records in the table. The indexes are not fragmented.

A query to get a count all points within 1000km of a specified point returns around 7.5m but takes 30+ seconds to execute.

The query plan shows use of the spatial index with cost 9% then clustered index seek on my primary key taking 83%.

I have tested STDistance and STBuffer - the latter is slightly faster.

SELECT COUNT(1) FROM testdoserate2 WHERE ([Location].STDistance('POINT (16.373813 48.230391)')) <  1000000
declare @referencepoint Geography = 'POINT (16.373813 48.230391)'
declare @radius Geography = @referencepoint.STBuffer(1000000);
SELECT count(1) FROM testdoserate2 WITH (nolock, INDEX(IDX_Location))
WHERE Location.Filter(@radius) = 1
Is there anything else I can possibly do to speed this up?

Viewing all 364 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>