代码之家  ›  专栏  ›  技术社区  ›  no11

PostgreSQL:为什么从同一个源表中“select into”比“select count”更快?

  •  0
  • no11  · 技术社区  · 1 年前

    将PG从11升级到15后,我遇到了以下情况:

    旧(工作)设置: Postgres 11 PostGIS 2.5

    设置: Postgres 15 PostGIS 3.3

    表_1(约14.000.000行)

    当我这样做的时候 select count(*) from table_1 它似乎永远不会结束。 当我这样做的时候 select * into table_2 from table_1 然后 select count(*) from table_2 ,它将在大约15分钟内完成。

    具体声明如下:

    -- this never stops
    select count(*)
    FROM table_1 t1
    INNER JOIN table_1 t2 ON (ST_Equals(t1.wkb_geometry, t2.wkb_geometry))
    WHERE t1.gid > t2.gid
    ;
    
    -- this works
    select *
    into table_2
    from table_1 
    ;
    select count(*)
    FROM table_2 t1
    INNER JOIN table_2 t2 ON (ST_Equals(t1.wkb_geometry, t2.wkb_geometry))
    WHERE t1.gid > t2.gid
    ;
    

    在这两种情况下,都会在wkb_geometry上创建一个索引,如下所示:

    CREATE INDEX table_1_geom ON table_1 
    USING gist (wkb_geometry)
    TABLESPACE pgdata;
    

    我已经在桌子上真空地重新创建了索引,但什么都没用。

    更新: 我发现问题出在gid列的pkey上。在选择进入。。。table2在gid上没有pkey。如果我删除table_1上的pkey,它也会工作。那么,在PG版本15中添加pkey差异会发生什么呢?有什么想法吗?

    更新2: 表_1的DDL/SQL

    SELECT ST_MakeLine(sp,ep) AS wkb_geometry, 
             ogc_fid,
             ...
        INTO table_1
        FROM
           (SELECT
              ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
              ST_PointN(geom, generate_series(2, ST_NPoints(geom)  )) as ep,
              ogc_fid,
              ...
            FROM
               (SELECT (ST_Dump(ST_Boundary(wkb_geometry))).geom, 
                       ogc_fid,
                       ...
               FROM another_table
               ) AS linestrings
            ) AS segments;
        
        ALTER TABLE table_1 ADD COLUMN gid serial NOT NULL;
        --ALTER TABLE table_1 ADD CONSTRAINT table_1_pk PRIMARY KEY (gid);
        CREATE INDEX table_1_geom ON table_1 USING gist (wkb_geometry) TABLESPACE pgdata;
    
    0 回复  |  直到 1 年前
        1
  •  -1
  •   Hogan    1 年前

    这个问题讨论了如何检查指数的统计数据

    How do I know if the statistics of a Postgres table are up to date?

    我认为问题可能是随着时间的推移,索引变得过时了——如果你不更新表上的统计数据,它们可能会“坏”,然后就无法工作。当你创建一个新表时,你会创建一个新索引,这样新表总是有新的统计数据。

    如果你懒得做这一切,你也可以删除索引并重新创建它。如果这解决了问题,那么你知道你需要设置一个后台作业来每隔一段时间(每周?)更新统计数据