这是来自 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) MS SQL 中的解决方案
MS SQL触发功能具有deleted与inserted在其中受操作的所有行存储系统表。您可以计算更新的行数:
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.6,OLD TABLE并NEW TABLE在 v10 中引入。
PostgreSQL 不允许在语句级触发器中引用旧表和新表,即包含所有旧行和/或新行的表,这些表由 SQL 标准中的 OLD TABLE 和 NEW TABLE 子句引用。
尝试使用 transaction_timestamp() 附加列
我可以DEFAULT transaction_timestamp()向主表添加特殊列,然后使用它来区分刚刚更新的行与其他行,但这不是解决方案,因为多个INSERTs/UPDATEs …
在这个答案中, Erwin 将IMMUTABLE函数分解为可以内联的函数和不能内联的函数。他有一个例子to_char(),表明IMMUTABLE函数 overto_char()实际上会更慢。
不过这很有趣,因为我什至不知道to_char()不是IMMUTABLE。此外,我不知道这IMMUTABLE会让任何事情变得更慢。我现在的问题是,如何确定标记为IMMUTABLE内联的函数是否被内联?
postgresql performance optimization execution-plan functions
我想在 postgresql 中为一个表创建一个触发器。我的表包含有关事件的数据,包括房间号、开始时间和事件持续时间。在新插入表时,我想检查新事件的房间号在新事件发生时是否会很忙。如果是这样,那么我想引发异常,否则将新事件插入表中。我想将触发器声明为instead of触发器,insert但 postgres 不允许在表instead of上insert操作触发器(我不想只为触发器创建视图)。
我该如何解决这个问题?理论上我可以创建一个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) 我有两个表:
account_id+amountaccount_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)
这给了我这些账户的所有提款。
现在,我想减去它们以返回我帐户的余额。创建这样的视图的最有效方法是什么?
在放弃 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
我将 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 中创建的物化视图。我想知道有没有办法 pg_dump 物化视图,就好像它们是表一样,所以当我将它们导入另一个数据库时,它会将其视为表而不是从其他表创建的视图?
出于测试目的,我使用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吗?
笔记:
我试过了
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 实例中以超级用户身份执行此操作。
据我了解,在 Postgres 中,过程用于操作数据,函数用于读取数据。我想要:
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 ×10
functions ×3
performance ×2
trigger ×2
amazon-rds ×1
explain ×1
index ×1
insert ×1
optimization ×1
pg-restore ×1
pgbouncer ×1
plpgsql ×1
postgis ×1
spatial ×1
transaction ×1
update ×1
view ×1