【问题标题】:Improving join query postgresql/postgis改进连接查询 postgresql/postgis
【发布时间】:2015-08-26 03:36:46
【问题描述】:

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

我有两张桌子:

  • 统计信息(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
);

每个表大约有 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)。

【问题讨论】:

  • 每张桌子的大小?我看到的唯一问题是likegeometry.id 是不同类型的statistics.id ??我不明白你的几何索引。对于 st_x。这对那个选择没有帮助。
  • 每张表有36582行
  • 表没有主键,所以哈希连接是你能得到的最好的。 (另外:使用文本字段作为 id 可能不是最佳选择)
  • @wildplasser 每个表的 id 上都有一个主要的。但是我得到了哈希连接。
  • 我怎么知道?你没有把它放在你的表定义中。顺便说一句:对于小表,散列连接没有任何问题。

标签: sql postgresql query-performance


【解决方案1】:

我认为您的查询没有任何问题。

检查事项

  • (geometry.id = (statistics.id)::text) 两个字段的数据类型相同吗?
  • WHERE statistics.id not like '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

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

【讨论】:

  • 感谢您的反馈。会尝试你的建议@Juan Carlos Oropeza
  • 转换坐标以将它们存储在几何表(x 和 y)中就可以了!我将时间除以 10。查询现在以 100 毫秒运行!谢谢@Juan Carlos Oropeza。
  • 但是,当我真正运行查询时,它仍然需要 5 秒才能运行,这比 6 秒要好......但我希望得到更好的结果。
  • 那么仍然有问题没有意义,查询那么慢。我在 ms 中查询了 1000 万行。您可以使用表格架构编辑您的帖子吗?除非您的驱动器速度较慢或内存设置错误。
  • 好的@Juan Carlos Oropeza。所以pg花那么多时间是不太对的。
猜你喜欢
  • 1970-01-01
  • 2019-07-27
  • 2016-03-28
  • 1970-01-01
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
  • 2021-08-30
  • 1970-01-01
相关资源
最近更新 更多