标签: postgresql

不断增加的列的总和

我有一个“交易”表,其中每笔交易都有一个金额:http : //sqlfiddle.com/#!15/42849/1

表中的记录永远不会被删除或更新。仅添加新交易。

我想计算金额的总和。对于每个请求,计算不必是 100% 最新的。

在大约一百万行的数据集上,这在我的数据库上大约需要 400 毫秒。这对于我的应用程序来说太慢了,我正在尝试找到加快速度的最佳解决方案。

到目前为止我尝试过的

  1. 物化视图:增加了必须运行 cronjob 的复杂性,它每 X 秒更新一次视图。
  2. 在应用服务器上缓存:当缓存需要更新时,每个 X 请求都会很慢。
  3. 存储对旧子集的查询结果:存储先前请求的 SUM 并使用这些来计算正确的总数。增加了复杂性。

PostgreSQL 是否提供了加速此类查询的解决方案?

更新 1

SUM 查询只是单列上的基本总和,所以我不相信这个查询本身可以变得更快。解决方案可能是进行某种缓存/预计算或类似操作。PostgreSQL 在这方面有什么特点吗?

更新 2

有问题的表:

CREATE TABLE transactions
(
  id bigserial NOT NULL,
  amount bigint NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

有问题的查询:

SELECT SUM(amount) FROM transactions;
Run Code Online (Sandbox Code Playgroud)

更新 3

我发现我实际上也需要一个“类型”。

更新表:

CREATE TABLE transactions
(
  id bigserial NOT NULL,
  amount bigint NOT NULL,
  type int NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

更新的查询:

SELECT SUM(amount) FROM transactions GROUP BY …
Run Code Online (Sandbox Code Playgroud)

postgresql

5
推荐指数
1
解决办法
689
查看次数

使用小 LIMIT 优化查询,对一列进行谓词并按另一列排序

我使用的是 Postgres 9.3.4,我有 4 个查询,它们的输入非常相似,但响应时间却大不相同:

查询#1

EXPLAIN ANALYZE SELECT posts.* FROM posts
WHERE posts.source_id IN (19082, 19075, 20705, 18328, 19110, 24965, 18329, 27600, 17804, 20717, 27598, 27599)
AND posts.deleted_at IS NULL
ORDER BY external_created_at desc
LIMIT 100 OFFSET 0;
                                                                                 QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.43..585.44 rows=100 width=1041) (actual time=326092.852..507360.199 rows=100 loops=1)
   ->  Index Scan using index_posts_on_external_created_at on posts  (cost=0.43..14871916.35 rows=2542166 width=1041) (actual time=326092.301..507359.524 rows=100 loops=1)
         Filter: (source_id = ANY ('{19082,19075,20705,18328,19110,24965,18329,27600,17804,20717,27598,27599}'::integer[]))
         Rows Removed by Filter: 6913925
 Total runtime: 507361.944 ms
Run Code Online (Sandbox Code Playgroud)

查询#2

EXPLAIN …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index optimization postgresql-9.3 postgresql-performance

5
推荐指数
1
解决办法
895
查看次数

SELECT 查询中未使用索引

我有一个大约 3.25M 行的表格,在 Postgres 9.4.1 中遵循以下格式

CREATE TABLE stats
(
    id serial NOT NULL,
    type character varying(255) NOT NULL,
    "references" jsonb NOT NULL,
    path jsonb,
    data jsonb,
    "createdAt" timestamp with time zone NOT NULL,
    CONSTRAINT stats_pkey PRIMARY KEY (id)
)
WITH (
    OIDS=FALSE
);
Run Code Online (Sandbox Code Playgroud)

type是一个简单的字符串长度不超过50个字符。

references列是一个带有键值列表的对象。基本上任何简单的键值列表,只有 1 级深,值总是字符串。它可能是

{
    "fruit": "plum"
    "car": "toyota"
}
Run Code Online (Sandbox Code Playgroud)

或者它可能是

{
    "project": "2532"
}
Run Code Online (Sandbox Code Playgroud)

createdAt时间戳并不总是从数据库中生成的(但它会默认如果值不被提供)

我目前使用的表格只有测试数据。在此数据中,每一行都有一个project键作为参考。所以有 3.25M 行有一个项目键。project引用正好有 400,000 个不同的值。该type字段只有 5 个不同的值,在生产中可能不会超过几百个。

所以我试图索引表以快速执行以下查询: …

postgresql performance index database-design postgresql-performance

5
推荐指数
1
解决办法
560
查看次数

PostgreSQL 的文件系统调优

我想在 Ubuntu 14.04 工作站中安装 PostgreSQL 9.x 版本,我正在寻找有关如何设置它的建议,以便

  • 获得良好的读写(50/50 平衡)性能

  • 保持整体常规系统使用的体面性能。

我的想法是在 SSD 驱动器中有两个主要分区:

  • [A] 带有操作系统推荐/默认设置的根系统(“/”)的 ext4。

  • [B] 一个用于 postgres 数据库文件(“/var/lib/pgsql”)的 ext4,具有大块大小(例如 1MB)和大预读大小(多少?)和适当的标志(哪个?)。

我不知道将 postgres db 文件与一般系统分开是否是一个好主意。在这种情况下,关于 [B] 块大小、预读大小、文件系统标志的任何建议?

此外任何有用的提示?

postgresql performance linux ubuntu postgresql-performance

5
推荐指数
1
解决办法
9144
查看次数

对数据库中的数据进行版本控制

我有一个数据库来保存有关projects.

项目有大量与它们相关的数据,这些数据被分割到其他表中,例如project_contactsproject_images。这些是一对多关系,其中 1 个项目可以有多个联系人和多个图像。

但是,我需要能够保留项目的“版本”。因此,如果更新了项目,则有关该项目的先前数据仍然存在。这是多对多关系的一个大问题。例如,有一个categories表,一个project_categories表——很多项目可以有很多类别。

当一个项目更新时,并不是每条数据都会更新。例如,如果一个项目有一个新联系人,它不会总是有一个新图像,因此图像表不会更新。

我考虑过的一种解决方案是拥有一个versions带有自动递增 ID的表;一project_id列和一time列。每个表也将获得一version_id列。每当更新项目时,都会在versions. 然后,当表被更新时,version_id也会被输入。这意味着有关项目的最新行project_images可能是 3,而最新版本project_contacts可能是 27。

由于version_id是递增的,因此获取单个项目的最新版本非常简单,因为您可以按最高version_id.

这个想法对我来说似乎失败的地方是,如果我想从特定日期获取项目的版本。

我可以使用我当前的解决方案来解决这个问题吗?

postgresql database-design

5
推荐指数
1
解决办法
3626
查看次数

SELECT + INSERT 或单独插入

我有一个应用程序,其中有几台设备每秒向我的服务器发送数据。在数据库上,我有一个包含设备的表和另一个每秒发送数据的表。

设备第一次发送数据时,服务器脚本应INSERT在设备表中注册 ( ) 该设备 ID 并将数据添加到数据表中。

我的问题是,什么会更快?

  1. 执行SELECT EXISTS查询以确定INSERT设备表中是否需要一个。如果SELECT EXISTS返回 false 则执行 an INSERT,否则什么都不做。

  2. 总是执行一个INSERT语句。考虑到设备 id 是表上的主键,如果设备已经存在它会返回一个错误,否则它会插入它。

只有第一次设备发送数据时才需要一个实际的INSERT,之后INSERT就不需要了。

PostgreSQL 版本是 9.4。

设备表定义如下:

CREATE TABLE common.tag
(
  customer integer,
  hostname character varying(150),
  description text,
  model integer,
  configprofile integer,
  id character varying(150) NOT NULL,
  host integer,
  CONSTRAINT tag_pk PRIMARY KEY (id),
  CONSTRAINT tag_fk_client FOREIGN KEY (customer)
      REFERENCES common.customer (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON …
Run Code Online (Sandbox Code Playgroud)

postgresql insert select referential-integrity

5
推荐指数
1
解决办法
2710
查看次数

多对一复制/事务复制

我在不同的地理位置(本地站点)有几个 PostgreSQL 数据库。

  • 每个本地站点 DB 都具有相同的架构,但具有唯一的数据。例如,以包含以下列的表为例:Site_ID、Department_ID、Department_Name。Site_ID 对于每个站点都是唯一的。

  • 我想将本地站点数据库中的所有数据收集到充当数据仓库的集中式数据库(再次是 PostgreSQL)中。

  • 集中式数据库上的相应示例表将具有与上述相同的列。所有本地站点数据都将进入此表。当然,每个站点数据由 Site_ID 指定。

问题:如何使用PostgreSQL 复制方法(流/多主 UDR/BDR/等)实现这一点。我看到这可以通过 SQLServer 使用Transactional Replication来完成。使用 PostgreSQL 实现此功能的最佳方法是什么?

限制:本地站点只能进行传出网络连接(即由于防火墙限制不能进行入站连接)

postgresql replication transactional-replication multi-master

5
推荐指数
1
解决办法
1418
查看次数

将 ROWTYPE 参数传递给 EXECUTE

我正在 Postgres 中开发一个函数,旨在为查询的每个记录恢复一组函数中包含的检查结果的值。只有这些函数之一会返回正确的值。这些函数有一个公共前缀“fn_condition_”,并接收一个“my_table”类型的对象作为参数。

由于进行检查的函数数量未知,我决定查阅 Postgres 目录,从表中pg_catalog.pg_proc搜索带有前缀“fn_condition_”的函数并使用EXECUTE.

我的问题是将参数传递给EXECUTE.

create or replace function test_conditions()
returns void as 
$$
declare
    v_record my_table%rowtype;
    v_function pg_proc%rowtype;    
begin 
    set search_path = 'pg_catalog';

    for v_record in (select * from my_table where id in (1,2,3)) loop
        for v_function in (
            SELECT  p.proname
            FROM    pg_namespace n
            JOIN    pg_proc p
            ON      p.pronamespace = n.oid
            WHERE   n.nspname = 'operacional'
            and p.proname like ('fn_condition\\_%')
            order by p.proname) 
        loop
         -- execute 'select ' || v_function.proname || '(' …
Run Code Online (Sandbox Code Playgroud)

postgresql dynamic-sql plpgsql postgresql-8.3

5
推荐指数
1
解决办法
2491
查看次数

从字符串中返回前 100 个单词

不确定这是否可行,但我想知道是否有任何方法可以使用 PostgreSQL 从包含不同长度的字符串的数据库列中返回前 100 个最常出现的单词?

该表包含约 250k 行,每行包含message许多其他元数据。那么,有没有办法筛选每一行中的每个单词,获取它出现的总次数并将其与同一列中所有其他单词的计数进行比较以返回前 100 个?

如果更容易,可以删除元数据以仅保留包含推文的列。

理想情况下,我希望能够执行该网站所做的工作以提供相同的输出,但只有更多的记录。

postgresql full-text-search

5
推荐指数
1
解决办法
3405
查看次数

了解 PostgreSQL 连接

我在 PostgreSQL 文档中看到了以下查询。不幸的是,我不明白加入标准。

create temp table tmp_stat_user_tables as select * from pg_stat_user_tables;

select * from pg_stat_user_tables n
join tmp_stat_user_tables t
on n.relid=t.relid
and (n.seq_scan,n.idx_scan,n.n_tup_ins,n.n_tup_upd,n.n_tup_del) <>
(t.seq_scan,t.idx_scan,t.n_tup_ins,t.n_tup_upd,t.n_tup_del);
Run Code Online (Sandbox Code Playgroud)

我需要如何理解 JOIN 子句?

这些表的用途以及第一个查询在做什么对我来说很清楚。

postgresql

5
推荐指数
1
解决办法
157
查看次数