簡體   English   中英

改進聯接查詢postgresql / postgis

[英]Improving join query postgresql/postgis

我相信postgresql可以更快地處理我的查詢,但是每次嘗試修改它都會使其變慢!

我有2張桌子:

  • 統計信息(id,field1,[...],field10)
  • 幾何(id,geom)

我在創建索引:

  • statistics.id
  • geometry.id
  • 幾何(st_x(st_centroid(st_transform(geom,2154))),st_y(st_centroid(st_transform(geom,2154))))

這是查詢

EXPLAIN ANALYZE SELECT 
statistics.*,
st_x(st_centroid(st_transform(geometry.geom, 2154))) AS x,
st_y(st_centroid(st_transform(geometry.geom, 2154))) AS y

FROM statistics
 JOIN geometry ON statistics.id = geometry.id 

WHERE statistics.id not like '97%';

這是結果

Hash Join  (cost=1294.66..5158.10 rows=36593 width=342) (actual time=20.788..1085.257 rows=36552 loops=1)
Hash Cond: (geometry.id = (statistics.id)::text)
->  Seq Scan on geometry  (cost=0.00..2445.46 rows=36593 width=279) (actual time=0.010..25.271 rows=36597 loops=1)
    Filter: (id !~~ '97%'::text)
->  Hash  (cost=835.96..835.96 rows=36696 width=69) (actual time=19.892..19.892 rows=36696 loops=1)
    Buckets: 4096  Batches: 1  Memory Usage: 3780kB
    ->  Seq Scan on statistics  (cost=0.00..835.96 rows=36696 width=69) (actual time=0.005..6.871 rows=36696 loops=1)
Planning time: 0.401 ms
Execution time: 1088.612 ms

最昂貴的操作是哈希聯接。 您將如何重組那里的查詢以獲得更好的結果?

下面是表的架構

CREATE TABLE "statistics" (
    "REG" integer,
    "DEP" character varying(10),
    "COM" character varying(50),
    "D03" integer,
    "D04" integer,
    "D05" integer,
    "D06" integer,
    "D07" integer,
    "D08" integer,
    "D09" integer,
    "D10" integer,
    "D11" integer,
    "D12" integer,
    "D13" integer,
    "id" text
);

CREATE TABLE geometry (  
    id text NOT NULL,
    id_geo numeric(10,0),
    cm_code character varying(3),
    name character varying(50),
    status character varying(20),
    lat integer,
    long integer,
    lat_centroid integer,
    long_centroid integer,
    z_ smallint,
    area numeric(10,0),
    population double precision,
    code_ct character varying(2),
    code_r character varying(1),
    code_dp character varying(2),
    name_dp character varying(30),
    code_rg character varying(2),
    geom geometry(MultiPolygon,4326),
    x real,
    y real
);

每個表中約有4萬行

索引已創建如下

CREATE INDEX statistics_id_idx ON public.statistics USING btree (id COLLATE pg_catalog."default");
CREATE INDEX geometry_geom_idx ON public.geometry USING gist (geom);
CREATE INDEX geometry_id_gin2 ON public.geometry  USING gin (id COLLATE pg_catalog."default" gin_trgm_ops);

對於信息,我嘗試了geometry_id和statistics_id的不同索引(btree和gin)。

我看不到您的查詢有任何問題。

檢查事項

  • (geometry.id = (statistics.id)::text)都是相同的數據類型嗎?
  • WHERE statistics.id not like '97%'; LIKE '%me'永遠不會使用索引,但是LIKE 'me%'可能會使用索引。 為什么不使用索引?
  • st_x(st_centroid(st_transform(geometry.geom, 2154))) AS x,是一個函數,需要花費時間。 需要先轉換坐標,然后提取一個值。 計算該值並將其存儲在字段中會更好。
  • 您的幾何索引對該查詢沒有任何影響,因為您正在計算不搜索內容的值。
  • 如果您要進行perfom地理搜索,那么兩者都不是正確的索引。 但是我們可以稍后再談

嘗試的事情

首先是where like

SELECT *
FROM statistics
WHERE statistics.id not like '97%';

然后只是join

SELECT statistics.*,
       geometry.geom
FROM statistics
JOIN geometry ON statistics.id = geometry.id 

然后加入+ st_x

SELECT statistics.*,
       st_x(st_centroid(st_transform(geometry.geom, 2154))) AS x,
       st_y(st_centroid(st_transform(geometry.geom, 2154))) AS y
FROM statistics
JOIN geometry ON statistics.id = geometry.id 

然后在geometry表中創建預先計算的x, y

SELECT statistics.*,
       geometry.x,
       geometry.y,
FROM statistics
JOIN geometry ON statistics.id = geometry.id 

然后加入+ st_x + where like然后加入+ geometry.xy +相同where like

比較每個步驟之間的時間,以檢查花費最多的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM