假设我们有以下查询:
1.
SELECT COUNT(*) FROM some_big_table WHERE some_col = 'some_val'
Run Code Online (Sandbox Code Playgroud)
2.
SELECT COUNT(*) FROM ( SELECT * FROM some_big_table WHERE some_col = 'some_val' )
Run Code Online (Sandbox Code Playgroud)
之前的任何查询是否性能更好?或者他们是一样的?
我使用的是 Postgresql 9.4,但是与其他 DBMS 有很大不同吗?
PS:我问这个问题是因为 SQLAlchemy 是一个基于 Python 的 ORM,COUNT它默认在子查询上执行操作,但有一个选项可以强制它COUNT直接在查询上执行。
postgresql performance subquery postgresql-9.4 sqlalchemy query-performance
出于开发目的,我们将生产数据库转储到本地。这很好,因为数据库足够小。公司在成长,我们希望降低风险。为此,我们希望在数据离开数据库服务器之前对其进行匿名化处理。
我们想到的一种解决方案是在 pg_dump 之前运行语句,但在同一个事务中,如下所示:
BEGIN;
UPDATE users
SET email = 'dev+' || id || '@example.com'
, password_hash = '/* hash of "password" */'
, ...;
-- launch pg_dump as usual, ensuring a ROLLBACK at the end
-- pg_dump must run with the *same* connection, obviously
-- if not already done by pg_dump
ROLLBACK;
Run Code Online (Sandbox Code Playgroud)
是否有现成的解决方案?我们的数据库托管在 Heroku 上,我们在转储方式上没有 100% 的灵活性。
我在下载和变体之前搜索了postgresql 匿名数据转储,但我没有看到任何高度相关的内容。
INSERT INTO当其中一些行的 PostGIS 几何类型的值与目标表中相应行的 PostGIS 几何类型不兼容时,使用单个语句将多行插入到表中会失败(如预期的那样):
CREATE EXTENSION postgis;
CREATE TABLE t (
id integer,
p geometry(POINT)
);
INSERT INTO t
VALUES
( 1, ST_GeometryFromText('Point(0 0)') ),
( 2, ST_GeometryFromText('Point(1 2)') ),
( 3, ST_GeometryFromText('MultiPoint(2 3)') ),
( 4, ST_GeometryFromText('Point(5 23)') ),
( 5, ST_GeometryFromText('Point(42 36)') );
Run Code Online (Sandbox Code Playgroud)
错误消息告诉我们到底出了什么问题:
CREATE EXTENSION postgis;
CREATE TABLE t (
id integer,
p geometry(POINT)
);
INSERT INTO t
VALUES
( 1, ST_GeometryFromText('Point(0 0)') ),
( 2, ST_GeometryFromText('Point(1 2)') ),
( 3, ST_GeometryFromText('MultiPoint(2 3)') ), …Run Code Online (Sandbox Code Playgroud) 我们有一个与世界断开连接的服务器。它是一款高端系统,具有 48GB 内存和 500GB SSD 硬盘,16 核 CPU。我们正在尝试做一个pg_restore少于 10 个表的简单数据库转储,没有二进制数据或 blob,只有简单的文本(注释系统)。但是一张表大约有200GB的数据,所以它很大。
这个数据库没有其他工作。仅此维护任务。鉴于上述配置,为此目的的最佳设置是什么?PGSQL 的文档对我帮助不大。我的具体问题是关于 wal 设置。
如果我们可以使用整个服务器来做一个pg_restore,并且这个服务器上除了 PG 之外没有其他东西,我们应该使用什么设置?这就是我们现在所拥有的:
maintenance_work_mem = 1500MB
fsync = off
synchronous_commit = off
wal_level = minimal
full_page_writes = off
wal_buffers = 64MB
#----- checkpoint_segments = 512
#----- max_wal_size = (3 * checkpoint_segments) * 16MB
#-- min_wal_size = 100MB # 80MB is the default
max_wal_size = 24576MB # based on 512 checkpoint_segments
max_wal_senders = 0
wal_keep_segments = 0
archive_mode = off …Run Code Online (Sandbox Code Playgroud) postgresql performance maintenance postgresql-9.6 postgresql-performance
我有一个功能 get_sa001 and a view Axis_RefCustomer.
当我get_sa001在一段时间内单独执行我的函数时,比如说 2016 - 2017,执行时间约为 6 秒。
SELECT d."Selling_date", d."Value_in_EUR", d."Value_in_currency", d."Site"
FROM report.get_sa001('2016-01-01'::date, '2017-03-31'::date, 32) AS d
Run Code Online (Sandbox Code Playgroud)
当我在视图上执行选择时Axis_RefCustomer,它运行大约 1 秒。
Select a."Selling_currency" FROM report."Axis_RefCustomer" AS a
Run Code Online (Sandbox Code Playgroud)
当我将它们连接在一起时,执行时间约为 39 秒!
SELECT d."Selling_date",
a."Selling_currency",
d."Value_in_EUR",
d."Value_in_currency",
d."Site"
FROM report.get_sa001('2016-01-01'::date, '2017-03-31'::date, 32) AS d
LEFT JOIN report."Axis_RefCustomer"
AS a ON d."Site" = a."Site"
AND d."Internal_reference" = a."Reference_internal"
AND d."Customer_code" = a."Customer_code"
Run Code Online (Sandbox Code Playgroud)
Is there anyway to reduce the amount of time my query …
当使用 pgAdmin 4(实际上是其他几个充当数据库客户端的程序)时,与服务器的连接在闲置 10 或 15 分钟后断开。一杯咖啡和一个电话,您会收到一条类似于“抱歉,与数据库的连接已丢失。您希望我尝试重新连接吗?”的消息。
而且pgAdmin重新连接总是需要多次尝试,并且已经展开的对象树被折叠了......所以,这有点烦人。
pgAdmin 似乎没有与该行为相关的任何参数。(似乎有一些方法可以更改某些连接超时,但它们与 pgAdmin 在服务器连接时间过长时的行为方式有关)。
可以做些什么来避免 pgAdmin 与数据库断开连接?
披露:这实际上是一个“伪问题”。它是另一个的衍生产品,最终与失去连接无关......鉴于我已经有了一个答案,我(不是很谦虚地)认为值得“问”,以防万一回答对某人有帮助。
我有这个 Postgres 功能。它强制文本为小写,所有空值变为空字符串,以便我更干净地执行搜索不匹配的内容等:
CREATE OR REPLACE FUNCTION magic_text(txt text) RETURNS text
IMMUTABLE PARALLEL SAFE
LANGUAGE SQL AS $$
SELECT lower(coalesce(txt,''))
$$;
Run Code Online (Sandbox Code Playgroud)
这个函数在许多不同的查询类型中被大量使用,所以我为它创建了所有种类的文本索引:
CREATE INDEX index_magic_cards_on_oracle_text_magic
ON magic_cards
USING BTREE (magic_text(oracle_text)) WITH (fillfactor = 100);
CREATE INDEX index_magic_cards_on_oracle_text_magic_text_pattern
ON magic_cards
USING BTREE (magic_text(oracle_text) text_pattern_ops) WITH (fillfactor = 100);
CREATE INDEX index_magic_cards_on_oracle_text_magic_gist_trgm
ON magic_cards
USING GIST (magic_text(oracle_text) gist_trgm_ops);
CREATE INDEX index_magic_cards_on_oracle_text_magic_gin_trgm
ON magic_cards
USING GIN (magic_text(oracle_text) gin_trgm_ops)
Run Code Online (Sandbox Code Playgroud)
这些索引以某种方式干扰了某些(但不是全部)类型的复杂正则表达式搜索。我无法确定特定的正则表达式符号或功能是否会导致问题。
这是一个示例(explain.depesz):
SELECT card_name
FROM magic_cards
WHERE magic_text(oracle_text) ~ '***:(?n)eldrazi\ (?!scion)';
Run Code Online (Sandbox Code Playgroud)
这不返回任何内容,并且根据查询规划器,它会在 上执行位图索引扫描 …
我有一张表,用于存储两个人之间的对话。
数据将如下所示:
CREATE TABLE foo
AS
SELECT $$[
{ "user": 1, "timestamp": 1, "message": "First message" },
{ "user": 2, "timestamp": 2, "message": "Second message" },
{ "user": 2, "timestamp": 3, "message": "Debounced message from same user" },
{ "user": 1, "timestamp": 4, "message": "Last message" }
]$$::jsonb AS jsondata;
Run Code Online (Sandbox Code Playgroud)
我从不需要单独查找每条消息,所以我只想将整个对话存储在一个jsonb字段中。我需要对所有消息执行全文搜索。
我的第一个想法是创建一个新的文本列,将所有消息连接到一个长字符串中,然后在该列上创建一个三元组 GIN 索引。
这似乎是一种浪费大量空间的 hack,所以我想避免中间列。如何直接从jsonb列创建索引?
该表reports按天分区表,例如reports_20170414,reports_20170415
约束 SQL 定义如下
CHECK (
rpt_datetime >= '2017-04-14 00:00:00+00'::timestamp with time zone
AND
rpt_datetime < '2017-04-15 00:00:00+00'::timestamp with time zone
)
Run Code Online (Sandbox Code Playgroud)
让我们考虑两种类型的查询
SELECT SUM(rpt_unique_clicks)
FROM reports WHERE rpt_datetime >= '2017-04-14 00:00:00';
Run Code Online (Sandbox Code Playgroud)
以上查询在亚秒内运行,一切正常。
SELECT SUM(rpt_unique_clicks)
FROM reports WHERE rpt_datetime >=
date_trunc('day', current_timestamp);
Run Code Online (Sandbox Code Playgroud)
相反,上面的查询运行至少 15 秒。
SELECT date_trunc('day', CURRENT_TIMESTAMP), '2017-04-14 00:00:00';
Run Code Online (Sandbox Code Playgroud)
返回
2017-04-14 00:00:00 +00:00 | 2017-04-14 00:00:00
Run Code Online (Sandbox Code Playgroud)
当我检查为什么后者运行时间长(使用解释分析)时,我完成了它访问并扫描每个表(~500)的结果,但前者仅访问,reports_20170414因此约束检查存在问题。
我想查询今天,而不是像后一个查询那样使用准备好的语句。为什么date_trunc('day', CURRENT_TIMESTAMP)不等于 2017-04-14 00:00:00?
postgresql constraint partitioning timestamp check-constraints
好的,我之前问过一个关于大型数据集的问题,但从未得到回答,所以我决定将其删减并询问先前设置的较小子集,并简化我在新问题中尝试完成的任务 - 希望这会清楚一点。
我有一个大表 ( report_drugs),它在磁盘上有 1775 MB,包含略多于 3300 万行。餐桌布置:
Column | Type | Modifiers
---------------+-----------------------------+-----------
rid | integer | not null
drug | integer | not null
created | timestamp without time zone |
reason | text |
duration | integer |
drugseq | integer |
effectiveness | integer |
Indexes:
"report_drugs_drug_idx" btree (drug) CLUSTER
"report_drugs_drug_rid_idx" btree (drug, rid)
"report_drugs_reason_idx" btree (reason)
"report_drugs_reason_rid_idx" btree (reason, rid)
"report_drugs_rid_idx" btree (rid)
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我有几个索引(并非都与这个问题相关)并且已经CLUSTER在drug列索引上编辑了表,因为这主要用于范围。VACUUM ANALYZE …
postgresql ×10
performance ×4
index ×2
client ×1
connectivity ×1
constraint ×1
functions ×1
heroku ×1
insert ×1
json ×1
maintenance ×1
network ×1
partitioning ×1
pg-dump ×1
pgadmin ×1
plpgsql ×1
postgis ×1
sqlalchemy ×1
subquery ×1
timestamp ×1