标签: postgresql-performance

可扩展查询前 x 天内的事件运行计数

我已经在stackoverflow上发布了这个问题,但我想我可能会在这里得到更好的答案。
我有一个表存储用户发生的数百万个事件:

                                       Table "public.events"
   Column   |           Type           |                         Modifiers                         
------------+--------------------------+-----------------------------------------------------------
 event_id   | integer                  | not null default nextval('events_event_id_seq'::regclass)
 user_id    | bigint                   | 
 event_type | integer                  | 
 ts         | timestamp with time zone | 
Run Code Online (Sandbox Code Playgroud)

event_type 有 5 个不同的值、数百万用户以及每个用户每个 event_type 的不同事件数,通常范围为 1 到 50。

数据样本:

+-----------+----------+-------------+----------------------------+
| event_id  | user_id  | event_type  |         timestamp          |
+-----------+----------+-------------+----------------------------+
|        1  |       1  |          1  | January, 01 2015 00:00:00  |
|        2  |       1  |          1  | January, 10 2015 00:00:00  | …
Run Code Online (Sandbox Code Playgroud)

postgresql performance scalability window-functions postgresql-performance

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

为什么 Postgres 需要这么长时间才能返回序列号?

我有一个应用程序可以批量加载到一个大表(1 亿行)中。我正在使用 Postgres 的COPY FROM功能从平面文件加载数据。目标表的主键为id

为了让批量插入工作,我使用以下方法为加载文件中的每一行创建了 id:

 SELECT  nextval('apps_id_seq'::regclass)
 FROM    "apps"
 ORDER   BY "apps"."id" ASC
 LIMIT   1 
Run Code Online (Sandbox Code Playgroud)

不幸的是,我没有看到这个查询花费的时间超过 150 秒。它会导致大量备份,因为其中一些文件包含数万行。

然而,当我在命令行运行它时,我得到了千分之一毫秒的返回结果。这是一个explain analyze

                                                            QUERY PLAN                                                                
------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.57..0.64 rows=1 width=4) (actual time=0.016..0.017 rows=1 loops=1)
   ->  Index Only Scan using apps_pkey on apps  (cost=0.57..15886651.40 rows=228128608 width=4) (actual time=0.015..0.015 rows=1 loops=1)
     Heap Fetches: 0
 Total runtime: 0.030 ms
Run Code Online (Sandbox Code Playgroud)

可能是什么导致了延迟?服务正在报告延迟NewRelic

postgresql performance postgresql-performance

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

单个数据库的 PostgreSQL fsync 关闭

我有一个存储在 PostgreSQL v9.4.4 中的写入密集型数据库,它会导致我的设备上出现 IO。我fsync只想关闭单个数据库,而不是 PostgreSQL 服务器范围。(我承认,当发生意外关闭时,它可能会导致损坏)。帮我看看如何制作。

postgresql performance postgresql-9.4 postgresql-performance

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

PostgreSQL 似乎在简单的条件连接中创建了低效的计划

考虑这两个查询:

SELECT
    t1.id, *
FROM
    t1
INNER JOIN
    t2 ON t1.id = t2.id
    where t1.id > -9223372036513411363;
Run Code Online (Sandbox Code Playgroud)

和:

SELECT
    t1.id, *
FROM
    t1
INNER JOIN
    t2 ON t1.id = t2.id
    where t1.id > -9223372036513411363 and t2.id > -9223372036513411363;
Run Code Online (Sandbox Code Playgroud)

注意:不是-9223372036513411363表中的最小值,并且条件将结果(从总行数 3.5 亿行)减少到 1700 万行。

就我个人而言,我希望 PostgreSQL 能够为这两个查询提供相同的计划,因为t1.id = t2.id自动意味着第二个条件。但不幸的是,PostgreSQL 正在创建两个不同的计划,第二个计划要好得多:

我非常喜欢第一个查询,因为我想从连接创建一个视图,并将 where 条件放在视图上的查询上,我在其中看到单个 id 列(我使用连接,USING因此单个 id 列在视图中可见) 。另外,我将连接两个以上的表,并且我不希望为每个连接添加这样的条件。

这种行为有什么原因吗?或者这是一个错误?有什么解决方法吗?

  • 替换ON …

postgresql performance join execution-plan postgresql-9.3 postgresql-performance

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

PostgreSQL 高磁盘 I/O

我正在评估 PostgreSQL 作为 Oracle 的替代品。我有一个包含 533 个表的数据库,其中最多包含 250,000 个条目。

\n\n

为了进行性能比较,我在 Oracle 和 PostgreSQL 上构建了数据库。

\n\n

然而,PostgreSQL 速度慢得多,并且它在 RAM 中存储的内容不多,而是具有大量的磁盘 I/O。

\n\n

我的性能测试:

\n\n
    \n
  • 将 50,000 个条目插入大约 250 列的表中
  • \n
  • 选择所有这些,包括不同表上的联接
  • \n
  • 更新附加“A”的字符串字段
  • \n
  • 删除引用表中的条目,这会导致所有条目被删除(在删除级联上)
  • \n
\n\n

我的系统配置:

\n\n
    \n
  • Windows 7、2 Xeons \xc3\xa0 8 核、32GB RAM、256GB SSD
  • \n
  • PostgreSQL 9.6
  • \n
  • 甲骨文 XE 11
  • \n
  • 玛丽亚数据库 10.2
  • \n
\n\n

以下是我测量的性能(5 次运行的平均值):

\n\n

比较

\n\n

NoTriggers 版本以ALTER TABLE x DISABLE ALL TRIGGERS.

\n\n

从图表中可以看出,PostgreSQL 并没有真正使用可用的 ram。\n查看资源监视器,它确实使用了高磁盘 io:

\n\n …

postgresql performance performance-testing postgresql-performance

5
推荐指数
0
解决办法
3758
查看次数

在冲突时更新具有相同值的目标列对性能的影响

这是一个关于 Postgres (v10) 的内部工作原理和性能的问题。

给定一个表 ,在和列github_repos上具有多列唯一索引,下面的两个批量更新插入操作之间是否存在任何性能差异(或其他需要注意的问题)?不同之处在于,在第一个查询中,和列包含在 UPDATE 中,而在第二个查询中则不包含。由于 UPDATE 在冲突时运行,因此和的更新值将与旧值相同,但这些列包含在 UPDATE 中,因为我正在使用的底层库就是这样设计的。我想知道按原样使用是否安全,或者我是否应该在更新中明确排除这些列。org_idgithub_idorg_idgithub_idorg_idgithub_id

查询#1:

INSERT INTO "github_repos" ("org_id","github_id","name")
VALUES (1,1,'foo')
ON CONFLICT (org_id, github_id)
DO UPDATE SET "org_id"=EXCLUDED."org_id","github_id"=EXCLUDED."github_id","name"=EXCLUDED."name"
RETURNING "id"
Run Code Online (Sandbox Code Playgroud)

查询#2:

INSERT INTO "github_repos" ("org_id","github_id","name")
VALUES (1,1,'foo')
ON CONFLICT (org_id, github_id)
DO UPDATE SET "name"=EXCLUDED."name"
RETURNING "id"
Run Code Online (Sandbox Code Playgroud)

github_repos桌子:

      Column       |       Type        | Collation | Nullable 
-------------------+-------------------+-----------+----------+
 id                | bigint            |           | not null |
 org_id            | bigint            |           | not null | …
Run Code Online (Sandbox Code Playgroud)

postgresql performance postgresql-performance

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

解决 PostgreSQL INSERT 性能不佳问题的系统配置

问题症状

postmaster与尝试插入低容量行的客户端连接相关的子进程的 CPU 使用率较高(导致插入的行比使用相同行慢 25 倍)。COPY ... FROM STDIN

背景

尝试识别系统/数据库配置以缓解上述较差的插入性能。我正在使用多线程 R 脚本来处理数据并将结果插入到 PostgreSQL 数据库中。我对 R 脚本进行了分析,以隔离调用的性能瓶颈DBI::dbBind(),同时用于top监视postmaster与子 R 线程打开的连接关联的子进程(请参阅下面的代码)。在 INSERT 期间,R 子进程大部分时间处于空闲状态(大概是在等待调用返回DBI::dbBind()),而postmaster子进程在其运行大约 2-3 分钟的时间内消耗了 95-100% 的 CPU。

系统/环境:

  • postgresql 版本 10.3(Fedora 包 10.3-5.fc27)
  • uname -a:Linux localhost 4.16.6-202.fc27.x86-64 #1 SMP Wed May 2 00:09:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  • /proc/cpuinfo: 16 个处理器 ( Intel(R) Xeon(R) CPU D-1541 @ 2.10GHz)
  • ulimit …

postgresql performance configuration r postgresql-10 postgresql-performance

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

为什么 EXPLAIN 不显示索引扫描的堆提取

我试图比较覆盖 b 树索引和简单 b 树索引之间的潜在性能差异,并与EXPLAIN(ANALYZE,BUFFERS)输出混淆。

测试环境

-- function to fill test table
CREATE OR REPLACE FUNCTION fillTable (n INTEGER)
   RETURNS INTEGER AS $rowsCount$
DECLARE
   counter INTEGER := 0 ;
BEGIN

   IF (n < 1) THEN
      RETURN 0 ;
   END IF;

   LOOP
      EXIT WHEN counter = n ;
      counter := counter + 1 ;
      insert into key_value_test(key, value) VALUES (counter,counter);
   END LOOP ;

   return counter;

END ;
$rowsCount$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

简单b-tree索引的测试用例

drop table key_value_test;
create table key_value_test
(
    key …
Run Code Online (Sandbox Code Playgroud)

postgresql performance postgresql-11 postgresql-performance

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

基于函数值的递归 CTE 在 Postgres 12 上明显慢于 11

跟进我关于 Postgres 12 中的某些查询比 11 中的查询慢的问题,我认为我能够缩小问题的范围。似乎基于函数值的递归 CTE 是有问题的地方。

我能够分离出一个相当小的 SQL 查询,它在 Postgres 12.1 上运行的时间比在 Postgres 11.6 上运行的时间要长得多,例如 Postgres 12.1 中的大约 150 毫秒与 Postgres 11.6 中的大约 4 毫秒。我能够在各种系统上重现这种现象:在 VirtualBox 中的多个 VM 上;通过两台不同物理机器上的 Docker。(有关 docker 命令,请参阅附录)。然而,奇怪的是,我无法在https://www.db-fiddle.com/上重现它(在那里看不到区别,两者都很快)。

现在进行查询。首先,我们创建这个简单的函数

CREATE OR REPLACE FUNCTION public.my_test_function()
 RETURNS SETOF record
 LANGUAGE sql
 IMMUTABLE SECURITY DEFINER
AS $function$ 

SELECT 
        1::integer AS id,
        '2019-11-20'::date AS "startDate",
        '2020-01-01'::date AS "endDate"

$function$;
Run Code Online (Sandbox Code Playgroud)

然后对于实际查询

WITH  "somePeriods" AS  (
      SELECT * FROM my_test_function() AS 
      f(id integer, "startDate" date, "endDate" …
Run Code Online (Sandbox Code Playgroud)

postgresql cte recursive postgresql-12 postgresql-performance

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

为什么 10,000 个 ID 的列表比使用等效的 SQL 来选择它们的性能更好?

我有一个带有遗留查询的 Rails 应用程序,我想对其进行翻新。当前实现执行两个 SQL 查询:一个获取大量 ID,第二个查询使用这些 ID 并应用一些额外的连接和过滤器来获得所需的结果。

我试图用避免往返的单个查询替换它,但这样做会导致我的本地测试环境(这是完整生产数据集的副本)的性能大幅下降。新查询中似乎没有使用索引,导致全表扫描。我曾希望单个查询能够保持与原始代码相同的性能,理想情况下,由于不需要发送所有 ID,因此可以对其进行改进

这是我实际问题的最小化版本。稍大一点的版本在讨论为什么10000个ID的列表中一个复杂的查询有更好的表现与多个热膨胀系数相比,相当于SQL选择它们?.

当前查询

有一个查询需要大约 6.5 秒来计算 10000 多个 ID 的列表。您可以visible_projects在下面的“建议查询”部分中将其视为 CTE 。然后将这些 ID 输入到此查询中:

EXPLAIN (ANALYZE, BUFFERS)
WITH visible_projects AS NOT MATERIALIZED (
    SELECT
        id
    FROM
        "projects"
    WHERE
        "projects"."id" IN (
            -- 10000+ IDs removed
)),
visible_tasks AS MATERIALIZED (
    SELECT
        tasks.id
    FROM
        tasks
    WHERE
        tasks.project_id IN (
            SELECT
                id
            FROM
                visible_projects))
SELECT
    COUNT(1)
FROM
    visible_tasks;
Run Code Online (Sandbox Code Playgroud)

查询计划(depesz

Aggregate  (cost=1309912.31..1309912.32 rows=1 width=8) (actual time=148.661..153.739 …
Run Code Online (Sandbox Code Playgroud)

postgresql performance query-performance postgresql-performance

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