gpt4 book ai didi

sql - 改进连接查询 postgresql/postgis

转载 作者:行者123 更新时间:2023-11-29 13:00:23 24 4
gpt4 key购买 nike

我相信 postgresql 可以更快地处理我的查询,但每次修改它的尝试都会使它变慢!

我有 2 个表:

  • 统计(id,field1,[...],field10)
  • 几何(id,geom)

我在 : 上创建了索引

  • statistics.id
  • 几何.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

最昂贵的操作是 Hash Join。您将如何重组那里的查询以获得更好的结果?

下面是表格的架构

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
);

每个表中大约有 40 000 行

索引已经创建如下

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 不像 '97%';LIKE '%me' 永远不会使用索引,但是 LIKE 'me%' 可能会使用索引。 Why doesnt use index?
  • st_x(st_centroid(st_transform(geometry.geom, 2154))) AS x, 是一个函数,这需要时间。需要转换坐标,然后提取一个值。如果计算该值并将其存储在一个字段中,您会更好。
  • 您的几何索引对该查询没有任何影响,因为您正在计算一个值而不是搜索某些内容。
  • 如果您想要执行索引不正确的地理搜索。但我们可以稍后再谈

尝试的事情

首先是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

比较每个步骤之间的时间以检查哪个步骤花费的时间最多。

关于sql - 改进连接查询 postgresql/postgis,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32217585/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com