执行 SQL 查询的普通 SQL 函数之间是否有区别:
create function get_sports() returns setof sport as
$body$
select * from sport;
$body$
language sql stable;
Run Code Online (Sandbox Code Playgroud)
和 PLPGSQL 函数返回相同的 SQL 查询:
create function get_sports() returns setof sport as
$body$
begin
return query select * from sport;
end
$body$
language plpgsql stable;
Run Code Online (Sandbox Code Playgroud)
关于性能?在什么情况下应该使用哪个版本?
如果我们传递参数,那会改变什么吗?如:
create function get_sports(status int) returns setof sport as
$body$
select * from sport where status = $1;
$body$
language sql stable;
create function get_sports(status int) returns setof sport as
$body$
begin
return …Run Code Online (Sandbox Code Playgroud) postgresql performance plpgsql functions postgresql-performance
除了“它发生”之外,我对任何数据库中的查询优化都没有清楚的了解。现在我刚刚看到了一篇“中等”的帖子,它讨论了在优化方面使用 PostgreSQL CTE 的陷阱,因为 CTE 只评估一次,并且任何可能在 CTE 使用方式、数据库方面应用的优化就是不能申请。
但是博客文章中的示例似乎很容易优化 - 即
SELECT * FROM foo WHERE id = 500000;
Run Code Online (Sandbox Code Playgroud)
对比
WITH cte AS (
SELECT * FROM foo
)
SELECT * FROM cte WHERE id = 500000;
Run Code Online (Sandbox Code Playgroud)
如果在第一个要求上懒惰地计算 CTE,那么我可以想象这两个查询可以以相同的方式进行优化(至少我认为)。
这让我想知道...... SQL Server 是否能够比 postgres 更好地优化这样的查询?
数据库之间在优化查询方面的程度/能力是否存在已知差异?
这项任务可能看起来很深奥,但我还是想创建某种 POC。
我的目标是让 PostgreSQL 数据库(版本 10)向使用它的应用程序公开一个 API。
API 需要采用一组 UDF 的形式:所有函数都属于一个公共方案,这是应用程序唯一可以访问的。桌子和其他东西隐藏在私人计划中。几乎就像,您知道的,面向对象的数据库。
这就是我试图让它发挥作用的原因:
好吧,没关系。
因此,当我尝试创建一些非常简单的函数(例如从表中获取所有记录)时,我提到它们总是比它包装的查询慢。虽然这本身是完全可以接受和理解的,但时间差异可能很大。因此,无法接受。
我有一张这样的桌子。
CREATE TABLE notifications (
id SERIAL PRIMARY KEY,
source_type INTEGER NOT NULL,
content JSONB,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(3)
)
Run Code Online (Sandbox Code Playgroud)
并且其中有 >120k 条记录。
想象一下,我们想要获得所有这些。
在这里,我们通过一个简单的查询来完成。没有索引,JSONB 数据几乎每条记录 1kb。
EXPLAIN (ANALYZE,VERBOSE,BUFFERS) SELECT * FROM private.notifications;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------
Seq Scan on private.notifications (cost=0.00..16216.13 rows=120113 width=877) (actual time=0.015..496.473 rows=120113 loops=1)
Output: id, source_type, content, created
Buffers: …Run Code Online (Sandbox Code Playgroud) postgresql performance plpgsql functions postgresql-performance
您可以通过手动编辑文件或调用命令来为 Postgres设置各种配置参数。这是编写设置的两种途径,但是阅读呢?postgresql.confALTER SYSTEM
? 有没有办法查询所有当前设置?
我知道客户端身份验证配置文件中的设置pg_hba.conf可以通过读取pg_hba_file_rules来看,是这样的:table pg_hba_file_rules ;。有类似的东西postgresql.conf吗?
请注意,下面的示例只是一个示例,我的场景要复杂得多,而且我尝试对其进行建模的方式确实很有意义
假设我正在我的一个应用程序中为审计事件创建一个表 - 所以所有的“event_created”、“user_created”等等。该表包含几列,其中一些是其他表的外键。随着时间的推移,这个单个表可以增长到数百万条记录。
从性能的角度来看,对所有这些事件使用单个表还是对每种事件使用单独的表并在单独的表上操作是更快、更高效?还是差别不大?为每种事件创建一个单独的表可能听起来很愚蠢,但您需要相信我,在我的现实世界场景中,这真的很有意义。
如何将texts 数组转换为UUIDs数组?
我需要join在两个表之间做一个:users和projects。
该users表有一个名为的数组字段,project_ids其中包含作为文本的项目 ID。
该projects表有一个名为 的 UUID 字段id。
我最初的想法是一个查询看起来像:
SELECT * FROM projects
JOIN users ON
projects.id = ANY(users.project_ids)
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为users.project_ids不是,UUID所以我试过:
projects.id = ANY(users.project_ids::uuid[])
Run Code Online (Sandbox Code Playgroud)
乃至:
projects.id = ANY(ARRAY[users.project_ids]::uuid[])
Run Code Online (Sandbox Code Playgroud)
但没有一个有效:
Run Code Online (Sandbox Code Playgroud)ERROR: invalid input syntax for type uuid: ""
更新
@a_horse_with_no_name 绝对正确。最好的选择应该是使用一组 UUID。
现在的问题是我如何可以改变的阵列text到阵列uuid?
该users表当前为空(0 条记录)。
我试过了
ALTER TABLE "users" ALTER COLUMN "project_ids" SET …Run Code Online (Sandbox Code Playgroud) 我经营一个非营利组织,致力于分享类似于维基百科的数据。
我们最近有一个客户想要我们的数据库的副本,我们意识到通过使用 PostgreSQL 的新逻辑复制,我们可以将我们的数据库表复制到他们控制的服务器上。
这对于完成我们共享数据的使命非常有用。它比提供慢速 API 好 100 倍。
我们为他们创建了一个这样的角色:
CREATE ROLE some_client WITH REPLICATION LOGIN PASSWORD 'long-password';
GRANT SELECT ON TABLE some_table TO some_client;
Run Code Online (Sandbox Code Playgroud)
我们为他们创建了一个 PUBLICATION,如下所示:
CREATE PUBLICATION testpublication FOR TABLE ONLY some_table;
Run Code Online (Sandbox Code Playgroud)
这样做有风险吗?我的分析是,这使他们可以选择访问他们正在复制到他们自己的服务器的表,但仅此而已。还有其他顾虑吗?如果有顾虑,是否有办法使这项工作发挥作用?我们有不想共享的表,但我们的大多数表只有公共数据。
试图想办法在不停机的情况下加速从属创建。
正常的做法是:
由于 2 在网络上可能需要很长时间,因此:
?
PostgreSQL 9.6。
create table jon.vins (vin citext primary key);
insert into jon.vins values
('3GNAXUEV1KL221776'),
('3GNAXHEV2KS548975');
CREATE TABLE jon.describe_vehicle (
vin citext primary key,
response jsonb);
Run Code Online (Sandbox Code Playgroud)
jon.describe_vehicle 仅包含 1 vin,3GNAXHEV2KS548975 的数据;
这个查询:
select a.vin,
b.response->'attributes'->>'bestMakeName' as make
from jon.vins a
left join jon.describe_vehicle b on a.vin = b.vin;
Run Code Online (Sandbox Code Playgroud)
返回我所期望的,每个 vin in 一行jon.vins:
vin | make
-------------------+-----------
3GNAXUEV1KL221776 |
3GNAXHEV2KS548975 | Chevrolet
(2 rows)
Run Code Online (Sandbox Code Playgroud)
但是这个查询:
select a.vin,
jsonb_array_elements(b.response->'style')->'attributes'->>'name' as style
from jon.vins a
left join jon.describe_vehicle b on a.vin = …Run Code Online (Sandbox Code Playgroud) 我创建了一个逻辑复制 PUBLICATION 使用FOR ALL TABLES. 现在我意识到我不想复制所有的表。我尝试从出版物中删除其中一个表格,但是:
mydb=# alter publication replicapublication drop table only migrations;
ERROR: publication "replicapublication" is defined as FOR ALL TABLES
DETAIL: Tables cannot be added to or dropped from FOR ALL TABLES publications.
Run Code Online (Sandbox Code Playgroud)
我已经完成了数百 GB 的巨大同步,而且我不想从新出版物开始。
问题: 1、本刊有赎回的希望吗?2. 如果没有,有没有办法创建一个完全同步的新发布,而不用完全同步重新开始?
谢谢。
postgresql ×10
replication ×3
functions ×2
performance ×2
plpgsql ×2
array ×1
cast ×1
cte ×1
join ×1
optimization ×1
query ×1
security ×1
sql-server ×1
uuid ×1