How to find the nearest point Postgis - postgresql

I have two tables in Postgis. Table of plats and table of kindergartens...
I would like to find the closest kindergraten from the given plat (ogc_fid=1397632) from another table. Both of them are points. I have tried something like that, but it still loading the result, probably something is wrong...
SELECT
name
FROM
kindergarten, plats
ORDER BY
ST_Transform(kindergarten.geom,5514) <->
(SELECT geom FROM plats where ogc_fid=1397632)
LIMIT 1;
Im not sure if can be a problem that table plats has SRID (Geometry(point,5514)) and table kindergartens has SRID (Geometry(point,3857) Those has been imported from OSM). Does it have some role that SRID is changed in SQL query and not before running them itself?
Do some of you know where is the problem? Im a beginner in spatial queries...
Thank you very much.

Related

Slow joining on primary key in postgresql

I'm using PostgreSQL 10.4 on Windows 10 and have observed this strange slowness.
create table stock_prices (
quote_date timestamp,
security_id int NOT NULL,
...
PRIMARY KEY (quote_date, security_id)
);
create index stock_prices_idx2 on stock_prices (security_id, quote_date);
Doing the following was instantaneous.
select * from stock_prices where quote_date = '2017-12-29';
But the following took 31s.
create temp table ts (
quote_date timestamp,
primary key (quote_date)
);
insert into ts values ('2017-12-29');
select p.*
from stock_prices p, ts t
where p.quote_date = t.quote_date;
drop table ts;
AFAIK, the above should hit the index. Using DBeaver's explain execution plan function, it's reporting that it did a "Seq Scan" on stock_prices, which I assume means table scan.
Before I moved to Postgres 10.4, I was using SQL Server 2017 Developer Edition with the exact same schema and didn't have any issues. The database is quote big so I couldn't really provide much test data, but the underlying data was straight from Wharton Business School's WRDS academic research database (the table I'm using is CRSP.dsf). Any idea why postgres isn't using the index?
[Edit] Ok, looks like it hugely depends on what Postgres thinks is in the temp table ts. Adding analyze ts; before the select made it instantaneous. This is bizarre but anyway...
There is also a primary key/index on the quote_date column in the ts table. Since you are doing an inner join here, the optimizer should be free to choose which table appears on the left and right sides of the join. Assuming it puts the stock_prices table on the left side, then it could take advantage of that index on the ts.quote_date column. But, in this case, it means it would be scanning the stock_prices table. So, perhaps the query plan changed when you switched versions of Postgres, but I don't see anything unexpected here. Postgres isn't using the index you asked about, because it seems to have found a better index/table to use.
As mentioned above, adding analyze ts will solve the problem. Looks like statistics have a great deal of influence over how Postgre plans its query.

ST_contains taking too much time

I am trying to match latitude/longitude to a particular neighbor location using below query
create table address_classification as (
select distinct buildingid,street,city,state,neighborhood,borough
from master_data
join
Borough_GEOM
on st_contains(st_astext(geom),coordinates) = 'true'
);
In this, coordinates is of below format
ST_GeometryFromText('POINT('||longitude||' '||latitude||')') as coordinates
and geom is of column type geometry.
i have already created indexes as below
CREATE INDEX coordinates_gix ON master_data USING GIST (coordinates);
CREATE INDEX boro_geom_indx ON Borough_GEOM USING gist(geom);
I have almost 3 million records in the main table and 200 geometric information in the GEOM table. Explain analyze of the query is taking so much time (2 hrs).
Please let me know, how can i optimize this query.
Thanks in advance.
As mentioned in the comments, don't use ST_AsText(): that doesn't belong there. It's casting the geom to text, and then going back to geom. But, more importantly, that process is likely to fumble the index.
If you're unique on only column then use DISTINCT ON, no need to compare the others.
If you're unique on the ID column and your only joining to add selectivity then consider using EXISTS. Do any of these columns come from the borough_GEOM other than geom?
I'd start with something like this,
CREATE TABLE address_classification AS
SELECT DISTINCT ON (buildingid),
buildingid,
street,
city,
state,
neighborhood,
borough
FROM master_data
JOIN borough_GEOM
ON ST_Contains(geom,coordinates);

Merge non-adjacent polygons in Qgis or Postgres

I am working with Qgis and PostgreSQL. But i can't figure out how to merge the non-adjacent polygons in my screenshot into one record? Can anybody help mee with this problem?
I want all the polygons with the same cat to be merged in one record.
See screenshot here:
Thnx
If you want use Postgres you need create a SELECT using ST_Union
geometry ST_Union(geometry set g1field);
geometry ST_Union(geometry g1, geometry g2);
geometry ST_Union(geometry[] g1_array);
You can try this to create one array
Concatenate multiple rows in an array with SQL on PostgreSQL
I try this one in my states tables and work ok
SELECT ST_Union(a_geom)
FROM (SELECT array_agg(e.geom) as a_geom
FROM mapas.estadosven_region e
) t
I make another test and looks like this also may work
SELECT ID, ST_Union(geom)
FROM test_dissolve_function t
WHERE ST_isValid(geom)='t'
GROUP BY ID;

PosgtreSQL Optimize Query with st_transform, st_makepoint, and st_contains

I have the following query:
UPDATE DestinTable
SET destin = geomVal
FROM GeomTable
WHERE st_contains(st_transform(geom, 4326), st_setsrid(
st_makepoint(d_lon::double precision, d_lat::double precision), 4326));
This query works, but it is very slow. I have to run an update on a very large table, and it is taking a 8+ hours to complete (I run this on 5 different columns). I wanted to know if there was a way to optimize this query to make it run faster. I am unaware of the behind the scenes work associated with an st_contains() method, so there may be some obvious solutions that I am missing.
The easiest way is to create an index on ST_TRANSFORM
CREATE INDEX idx_geom_4326_geomtable
ON GeomTable
USING gist
(ST_Transform(geom, 26986))
WHERE geom IS NOT NULL;
If you have all the fields in one SRID in the table it will be even easier to create a normal GIST index on that table and transform the point you're supplying to the local SRID

How do I use ST_Contains in following case?

I have two tables. First with points, and second with polygons. I need to find out which points are in required polygon according to the attribute gid.
Using query: SELECT table1.* FROM table1, table2 WHERE table2.gid=1 AND ST_Contains(table2.geom2, table1.geom1);
What I get is empty table (only columns without data)...
Tnx
Are you sure there are any intersecting points? Try
SELECT COUNT(*) FROM table2 WHERE table2.gid=1
It should return 1.
Another thing you could try is using ST_Intersects instead of ST_Contains.
Otherwise, you might need to post some data dumps of data you think should match.