标签: postgresql

管理和加速对超过 3 万亿行的 PostgreSQL 表的查询

我有超过 10 年的时间序列数据,有超过 3 万亿行和 10 列。

目前我使用具有 128GB RAM 的 PCIe SSD,我发现查询需要大量时间。例如,运行以下命令需要超过 15 分钟:

SELECT * FROM tbl WHERE column_a = 'value1' AND column_b = 'value2';
Run Code Online (Sandbox Code Playgroud)

该表主要用于读取。写入表的唯一时间是在每周更新期间插入大约 1500 万行。

管理如此大的表的最佳方法是什么?您会建议按年份拆分吗?

表大小为 542 GB,外部大小为 109 GB。

EXPLAIN (BUFFERS, ANALYZE) 输出:

"Seq Scan on table  (cost=0.00..116820941.44 rows=758 width=92) (actual time=0.011..1100643.844 rows=667 loops=1)"
"  Filter: (("COLUMN_A" = 'Value1'::text) AND ("COLUMN_B" = 'Value2'::text))"
"  Rows Removed by Filter: 4121893840"
"  Buffers: shared hit=2 read=56640470 dirtied=476248 written=476216"
"Total runtime: 1100643.967 ms"
Run Code Online (Sandbox Code Playgroud)

该表是使用以下代码创建的:

CREATE TABLE …
Run Code Online (Sandbox Code Playgroud)

postgresql index database-design database-recommendation partitioning

7
推荐指数
1
解决办法
2102
查看次数

向表中添加新的空列导致锁定

昨天我们在我们的生产数据库上运行了一个我们认为是安全的模式迁移,但遇到了一个问题。似乎添加新列会导致锁定,我们的应用程序无法再访问该表。以下是迁移前对表的说明:

                                                                    Table "public.facilities"
              Column               |            Type             |                        Modifiers                        | Storage  | Stats target | Description
-----------------------------------+-----------------------------+---------------------------------------------------------+----------+--------------+-------------
 id                                | integer                     | not null default nextval('facilities_id_seq'::regclass) | plain    |              |
 name                              | character varying(255)      |                                                         | extended |              |
 phone                             | character varying(255)      |                                                         | extended |              |
 time_zone                         | character varying(255)      |                                                         | extended |              |
 company_id                        | integer                     |                                                         | plain    |              |
 created_at                        | timestamp without time zone |                                                         | plain    |              |
 updated_at                        | timestamp without time zone …
Run Code Online (Sandbox Code Playgroud)

postgresql postgresql-9.3

7
推荐指数
1
解决办法
4504
查看次数

PostgreSQL:错误:无法在只读事务中执行 CREATE DATABASE

我安装了 PostgreSQL 及其 GUI,pgAdmin III。
安装程序已经有一个默认的数据库 postgres。

当我尝试创建新表或数据库时,显示错误:

错误:无法在只读事务中执行 CREATE DATABASE

我取消注释default_transaction_read_only = offpostgresql.conf 中的行并执行命令,pg_ctl start -D /home/jaison/progresData -Z datanode -l logfile但它仍然显示相同的错误。

请帮我解决这个问题。

postgresql

7
推荐指数
1
解决办法
2万
查看次数

从 %current% 表中选择的 PostgreSQL 触发器函数

我有多个具有相同列名的表,它们仅在列值上有所不同,例如:

tbl_log_a
tbl_log_b
tbl_log_c
...
Run Code Online (Sandbox Code Playgroud)

从 a 到 z 的 26 个表。每个表都有一个触发器,它调用一个触发器函数,它执行完全相同的操作:

SELECT columnname FROM tbl_log_a
Run Code Online (Sandbox Code Playgroud)

除此之外,我所有的触发器功能都做同样的事情。它们的不同之处在于:

select columnname FROM tbl_log_a
select columnname FROM tbl_log_b
select columnname FROM tbl_log_c
...
Run Code Online (Sandbox Code Playgroud)

所以我必须创建 26 个触发函数,每个tbl_log_%letter%. 有没有办法告诉触发器函数:

SELECT columnname FROM %currenttable%
Run Code Online (Sandbox Code Playgroud)

通过%currenttable%我的意思是当触发放在桌子上。或者:

SELECT columnname FROM tbl_log_%letter%
Run Code Online (Sandbox Code Playgroud)

Postgres 9.1 中可能吗?我正在阅读动态确定的表。有什么线索吗?我想将表名本身存储在一个变量中,而不是该表中的列,因为触发器函数适用于该表中的多个列。

TG_TABLE_NAME
TG_TABLE_SCHEMA
Run Code Online (Sandbox Code Playgroud)

postgresql trigger dynamic-sql plpgsql functions

7
推荐指数
1
解决办法
4826
查看次数

获取每个 ID 的最后 5 个不同值

我正在使用 PostgreSQL 9.4。

我有一个包含以下条目的表:

 id | postcode | date_created
 ---+----------+-----------------
 14 | al2 2qp  | 2015-09-23 14:46:57
 14 | al2 2qp  | 2015-09-23 14:51:07
 14 | sp2 8ag  | 2015-09-23 14:56:11
 14 | se4      | 2015-09-23 16:12:05
 17 | e2       | 2015-09-23 16:15:35
 17 | fk20 8ru | 2015-09-23 16:28:35
 17 | fk20 8ru | 2015-09-23 16:35:51
 17 | se2      | 2015-09-23 16:36:17
 17 | fk20 8ru | 2015-09-23 16:36:22
 17 | fk20 8ru | 2015-09-23 16:37:04
 17 | se1 …
Run Code Online (Sandbox Code Playgroud)

postgresql greatest-n-per-group distinct

7
推荐指数
2
解决办法
1万
查看次数

如何编码已知日期但未知年份?

我正在使用 Postgres 数据库,并且有一个带有日期时间字段的表。对于许多记录,我们知道年份但不知道日期。有时我们知道日期但不知道年份。其他时候我们知道时间但不知道日期。

使用日期时间数据类型时如何存储部分日期信息?

postgresql best-practices datetime date

7
推荐指数
1
解决办法
294
查看次数

Postgres 刷新物化视图锁

我在 Postgres 中有一个物化视图,想知道刷新该视图时取出了哪些锁(如果有)。

CREATE TABLE people ( name VARCHAR(30) );
INSERT INTO people VALUES ('Alice'), ('Bob'), ('Cher');
CREATE MATERIALIZED VIEW test AS SELECT * FROM people;
REFRESH MATERIALIZED VIEW test;
Run Code Online (Sandbox Code Playgroud)

具体来说,我试图了解该REFRESH MATERIALIZED VIEW命令是否取出ACCESS EXCLUSIVE锁。

我尝试了一个解释但没有成功:

#> EXPLAIN REFRESH MATERIALIZED VIEW test;

                QUERY PLAN                 
-------------------------------------------
Utility statements have no plan structure
Run Code Online (Sandbox Code Playgroud)

postgresql materialized-view

7
推荐指数
1
解决办法
5491
查看次数

通过 pg_hba.conf 文件之外的 IP 地址限制 Postgres 角色

我目前正在向目前仅支持 MySQL 的部署工具添加 Postgres 支持。该工具动态提供和配置数据库等。

在 MySQL 中,我们可以使用 SQL 将用户限制为一组特定的 IP 地址,作为授权命令的一部分,如下所示:

GRANT ALL PRIVILEGES ON my_database_name.* TO 'my_user_name'@'192.168.101.%' IDENTIFIED BY 'my_secret_password'
GRANT ALL PRIVILEGES ON my_database_name.* TO 'my_user_name'@'internal.example.com' IDENTIFIED BY 'my_secret_password'
Run Code Online (Sandbox Code Playgroud)

在 Postgres 中,似乎设置类似安排的唯一方法是首先无限制地创建用户:

CREATE USER "my_user_name" WITH PASSWORD 'my_secret_password'
Run Code Online (Sandbox Code Playgroud)

我已经整理出如何以编程方式将此角色限制到特定数据库,但似乎通过主机限制 Postgres 用户的唯一方法是在 pg_hba.conf 文件中创建条目。

这是有问题的,因为没有文件系统访问权限的代理以编程方式创建了许多用户/主机。

看起来我们围绕这个的唯一三个选择是:

  1. 在使用 SQL 创建角色后,不使用 SQL 来操作 pg_hba.conf 来限制角色
  2. 对于允许的主机,允许“所有”,而不是特定用户
  3. 仅限制对 localhost 的访问,并使用 ssh 隧道进行连接

这似乎不太理想,让我怀疑我是否忽略了一个明显的解决方案。是否可以仅使用 SQL 命令通过 IP 地址限制 Postgres 角色?

mysql postgresql permissions

7
推荐指数
1
解决办法
3932
查看次数

“合并” Postgres 表中的两行,带有外键

我使用 PostgreSQL 中的以下两个表来保存我读过的书籍的数据库:

CREATE TABLE authors (
    id SERIAL PRIMARY KEY,
    name text
);

CREATE TABLE books (
    id SERIAL PRIMARY KEY,
    title text,
    author_id integer REFERENCES authors(id) ON UPDATE CASCADE ON DELETE CASCADE,
    UNIQUE(title, author_id)
);
Run Code Online (Sandbox Code Playgroud)

现在,在浏览我的作者列表时,我发现了以下两个条目:

id | name
----------
 1 | Mark Twain
 2 | Samuel Clemens
Run Code Online (Sandbox Code Playgroud)

我想要做的是删除“马克吐温”条目,并有效地更新所有引用“马克吐温”的书籍以引用“塞缪尔克莱门斯”。我知道我可以手动执行此操作,但我想要一个有效的解决方案,无论哪些表正在引用authors(id)

我想过这样做(在交易中):

  1. 将 Mark Twain 更改id为 2,让我们UPDATE CASCADE负责更改引用。
  2. 删除马克吐温条目

但这会遇到一些问题,主要是:

  1. 第一步创建一个重复的主键
  2. 一旦它们都具有相同的 ID,我不确定如何引用要删除的正确行!
  3. DELETE CASCADE让我担心的第二个步骤

还有一个更微妙的问题,可以用我(精心策划的)books表格的一部分来说明:

id | title              | …
Run Code Online (Sandbox Code Playgroud)

postgresql foreign-key referential-integrity postgresql-9.4

7
推荐指数
1
解决办法
4247
查看次数

PostgreSQL 数据文件的大小大于数据本身

我们有一个系统可以将一些数据归档到 PostgreSQL 数据库。我们发现由于数据库归档,PC 存储空间已满。问题是我检查了驻留在其中的数据文件/var/lib/pgsql/data/base/,它们总共大约 70 GB,而当我使用pg_dump输出文件转储所有数据库时,它们没有超过 24 GB。我在这里遗漏了什么或误解了什么?这么大的尺寸差异去哪儿了?

编辑:我确实pg_dump包含模式和数据,并带有-c允许删除和创建的选项。

编辑 2:我调查了 DB 模式文件,发现包含 24 GB(约 3.324 亿行)数据中的近 23.9 GB 的表上有一个索引。另一个表上有另一个索引,但该表为空。

编辑 3:程序定期存储大约 1500 个变量的值,我的意思是所有变量的记录时间为 0.1 秒到 1 分钟或更长时间,所以我认为这里有一个巨大的数据库访问。

编辑 4:我在这里执行第二个查询以查找模式中每个关系的大小,我发现以下内容:

  • 28 GB 用于主数据表。
  • 大约 42 GB 仅用于 3 个索引!24、9、9。

我的目的是我想经常(每隔几个月)进行一次备份和恢复。在进行备份和恢复时,我应该关心这些数据库索引还是只关注我的数据表?

postgresql storage

7
推荐指数
2
解决办法
1万
查看次数