标签: postgresql

没有“有损”的“索引重新检查删除的行”是什么意思?

这是来自 Postgres 9.6 的 EXPLAIN ANALYZE 的一部分:

->  Bitmap Heap Scan on cities  (cost=90.05..806.49 rows=265 width=4) (actual time=4.733..45.772 rows=17 loops=1)
       Recheck Cond: (regexp_replace(regexp_replace(replace(replace(replace(replace(lower(name), 'ä'::text, 'ae'::text), 'ö'::text, 'oe'::text), 'ü'::text, 'ue'::text), 'ß'::text, 'ss'::text), 'strasse\M'::text, 'strasse'::text, 'g'::text), '\W'::text, ''::text, 'g'::text) % 'coerde'::text)
      Rows Removed by Index Recheck: 567
      Heap Blocks: exact=497
      ->  Bitmap Index Scan on city_lookup_index  (cost=0.00..89.98 rows=265 width=0) (actual time=4.229..4.229 rows=584 loops=1)
             Index Cond: (regexp_replace(regexp_replace(replace(replace(replace(replace(lower(name), 'ä'::text, 'ae'::text), 'ö'::text, 'oe'::text), 'ü'::text, 'ue'::text), 'ß'::text, 'ss'::text), 'strasse\M'::text, 'strasse'::text, 'g'::text), '\W'::text, ''::text, 'g'::text) % 'coerde'::text) …
Run Code Online (Sandbox Code Playgroud)

postgresql execution-plan explain postgresql-9.6

3
推荐指数
1
解决办法
654
查看次数

如何从 PostgreSQL 中的触发器访问其他 INSERTed/UPDATEd 行?

MS SQL 中的解决方案

MS SQL触发功能具有deletedinserted在其中受操作的所有行存储系统表。您可以计算更新的行数:

set @updatedCount = (select count(*) from deleted)
Run Code Online (Sandbox Code Playgroud)

或找出最小值:

set @updatedMinimumCol1 = (select min(col1) from deleted)
Run Code Online (Sandbox Code Playgroud)

PostgreSQL 的问题

对于FOR EACH ROW触发器,我可以使用 OLD 和 NEW 系统记录,但它们每次调用触发器只存储 1 行。触发器的调用是分开的,所以如果用户更新 10 行,触发器将被调用 10 次,但每次我只能知道 1 个当前行,而不是所有 10 行。

因为FOR EACH STATEMENT我根本不知道任何访问更新行的机制。我使用 PostgreSQL v9.6OLD TABLENEW TABLE在 v10 中引入。

PostgreSQL 不允许在语句级触发器中引用旧表和新表,即包含所有旧行和/或新行的表,这些表由 SQL 标准中的 OLD TABLE 和 NEW TABLE 子句引用。


尝试使用 transaction_timestamp() 附加列

我可以DEFAULT transaction_timestamp()向主表添加特殊列,然后使用它来区分刚刚更新的行与其他行,但这不是解决方案,因为多个INSERTs/UPDATEs …

postgresql trigger postgresql-9.6

3
推荐指数
1
解决办法
8728
查看次数

如何确定是否可以内联 SQL 函数?

这个答案中, Erwin 将IMMUTABLE函数分解为可以内联的函数和不能内联的函数。他有一个例子to_char(),表明IMMUTABLE函数 overto_char()实际上会更慢

不过这很有趣,因为我什至不知道to_char()不是IMMUTABLE。此外,我不知道这IMMUTABLE会让任何事情变得更慢。我现在的问题是,如何确定标记为IMMUTABLE内联的函数是否被内联?

postgresql performance optimization execution-plan functions

3
推荐指数
1
解决办法
312
查看次数

如何在postgres的表上创建`而不是`触发器?

我想在 postgresql 中为一个表创建一个触发器。我的表包含有关事件的数据,包括房间号、开始时间和事件持续时间。在新插入表时,我想检查新事件的房间号在新事件发生时是否会很忙。如果是这样,那么我想引发异常,否则将新事件插入表中。我想将触发器声明为instead of触发器,insert但 postgres 不允许在表instead ofinsert操作触发器(我不想只为触发器创建视图)。

我该如何解决这个问题?理论上我可以创建一个after触发器,然后检查新插入的数据是否有效,如果无效则删除。但这在概念上似乎是错误的方法,实际上也可能是错误的(我不确定触发器是否是原子的,也许有人可能已经根据错误的数据做出了错误的决定)。

这是表定义:

create table room_schedule(
  start_date date,
  start_time time,
  room_no int,
  event_id int,
  duration interval,
  primary key(start_date, start_time, room_no, event_id)
);
Run Code Online (Sandbox Code Playgroud)

这是我的触发器和函数定义:

create or replace function inserttrigfunc() returns trigger as $$
declare count int;

begin

with end_time_table(eid, stime, etime) as (
        select event_id, start_time, (start_time + duration) as etime from room_schedule
        where room_no=new.room_no
    ),
        overlapping_time_table(eid, stime, etime) as(
            select * from end_time_table
            where …
Run Code Online (Sandbox Code Playgroud)

postgresql trigger insert functions

3
推荐指数
1
解决办法
1529
查看次数

如何从不同的表中减去列的总和?

我有两个表:

  1. 提款:account_id+amount
  2. 奖品:account_id+amount

我想计算每个 的余额account,可能在VIEW.

我可以有两个查询:

SELECT account_id, SUM(amount) FROM prizes GROUP BY account_id
Run Code Online (Sandbox Code Playgroud)

这给了我每个帐户的总奖金,以及:

SELECT account_id, SUM(amount) FROM withdrawals GROUP BY account_id
Run Code Online (Sandbox Code Playgroud)

这给了我这些账户的所有提款。

现在,我想减去它们以返回我帐户的余额。创建这样的视图的最有效方法是什么?

postgresql view

3
推荐指数
1
解决办法
5498
查看次数

PostgreSQL 地理空间查询很慢

在放弃 MySQL 之后,我尝试了 Elasticsearch,现在不想看看我是否可以使用 PostgreSQL/PostGIS,因为它可以让我只使用 PostgreSQL。

我需要按距离(不能完全相同)从表中获取记录并按距离排序。该表有 1000 万条记录。

当我在 PostgreSQL 上查询比在 MySQL 上的查询速度慢时,我想我一定做错了什么。

我可以做什么更好?

桌子:

id | hash_id | town | geo_pt2 

geo_pt2 is geography
Run Code Online (Sandbox Code Playgroud)

指数:

CREATE INDEX geo_pt2_gix ON public.member_profile USING gist (geo_pt2)
Run Code Online (Sandbox Code Playgroud)

询问:

SELECT hash_id, town
     , ST_Distance(t.x, geo_pt2) AS dist
FROM   member_profile, (SELECT ST_GeographyFromText('POINT(47.4667 8.3167)')) AS t(x)
WHERE  ST_DWithin(t.x, geo_pt2, 250000)
ORDER  BY dist
limit 100 offset 1000;
Run Code Online (Sandbox Code Playgroud)

解释:

Limit  (cost=9.08..9.08 rows=1 width=53)
  ->  Sort  (cost=9.07..9.08 rows=1 width=53)
        Sort Key: (_st_distance('0101000020E610000088855AD3BCBB474052499D8026A22040'::geography, member_profile.geo_pt2, '0'::double precision, true))
        -> …
Run Code Online (Sandbox Code Playgroud)

postgresql performance spatial postgis postgresql-10 postgresql-performance

3
推荐指数
1
解决办法
503
查看次数

PgBouncer“不允许更多连接(max_client_conn)”

我将 PostgreSQL 与 PgBouncer 一起使用,并在我的应用程序中收到以下错误:

08P01:不允许更多连接(max_client_conn)

pgbouncer.ini 有以下配置:

max_client_conn = 100
default_pool_size = 20
pool_mode = session
Run Code Online (Sandbox Code Playgroud)

postgresql.conf 有:

max_connections = 100
Run Code Online (Sandbox Code Playgroud)

PostgreSQL 服务器有 5 个由单个用户访问的数据库。

我的理解是max_connections应该等于(default_pool_size * # databases),并且max_client_conn至少应该是这么多。我还看到 pgbouncer.ini 中的注释default_pool_size应该等于max_client_connif using session pooling。

所以要解决我遇到的这个错误,我应该简单地设置default_pool_size = 100吗?还是只增加max_client_conn?或者是其他东西?

postgresql pgbouncer postgresql-9.4

3
推荐指数
1
解决办法
6078
查看次数

从 postgresql 导出物化视图作为表?

我有一个在 Postgresql 中创建的物化视图。我想知道有没有办法 pg_dump 物化视图,就好像它们是表一样,所以当我将它们导入另一个数据库时,它会将其视为表而不是从其他表创建的视图?

postgresql materialized-view

3
推荐指数
1
解决办法
2261
查看次数

在更新整个表之前暂时禁用索引

出于测试目的,我使用pg_restore. 在新数据库中,我运行匿名化敏感数据的 SQL 查询。但是,像下面这样的查询会更新一个表中超过 2000 万条记录,该表具有约 10 个索引(在 期间创建pg_restore)。

UPDATE users SET email = users.id || '@example.com',
phone_number = NULL;
Run Code Online (Sandbox Code Playgroud)

这需要几个小时的当前设置。

为了加快速度,我想为了运行而禁用表的索引update,然后再次启用它们并重新索引表。我怎样才能做到这一点?还有其他方法可以加快速度UPDATE吗?

笔记:

  1. 我试过了

    UPDATE pg_index
    SET indisready=false
    WHERE indrelid = (
        SELECT oid
        FROM pg_class
        WHERE relname='users'
    );
    
    Run Code Online (Sandbox Code Playgroud)

但得到了下面的错误。

ERROR:  permission denied for relation pg_index
Run Code Online (Sandbox Code Playgroud)

显然,您不能在 AWS RDS PostgreSQL 实例中以超级用户身份执行此操作。

  1. 删除索引然后再次创建它们会很不方便,因为我必须提前知道它们涵盖哪些列。理想情况下,我会有一个命令将现有的索引配置存储在某个临时变量中,然后使用此信息重新创建它们。

postgresql index update pg-restore amazon-rds

3
推荐指数
1
解决办法
1689
查看次数

如何在过程(不是函数)中使用变量?

据我了解,在 Postgres 中,过程用于操作数据,函数用于读取数据。我想要:

  1. 声明一个变量
  2. 选择一个值到一个变量中
  3. 将变量插入另一个表
  4. 在事务中执行此操作
  5. 在存储过程中执行此操作
  6. 必要时回滚

CREATE PROCEDURE test_variable()
LANGUAGE SQL
AS $$
    BEGIN;
        DECLARE some_id INTEGER;
        SELECT nextval('some_sequence') INTO some_id;
        INSERT INTO some_table (some_column) VALUES (some_id);
    END;
$$;
Run Code Online (Sandbox Code Playgroud)

以上对我不起作用。当我寻找解决方案时,有很多不同的变量涉及函数$$、声明、事物不返回任何内容;似乎找不到一个简单的例子;我只需要一个清晰的语法示例。

postgresql transaction plpgsql functions sql-procedure

3
推荐指数
1
解决办法
9629
查看次数