标签: postgresql-performance

postgresql - 索引如何以及为什么比它们的表大

我正在使用 postgresql 9.3 并试图了解索引如何以及为什么比它们的表大。

示例输出:

 database_name | database_size |                          table_name                          | table_size | indexes_size | total_size
---------------+---------------+--------------------------------------------------------------+------------+--------------+------------
 foo_12345 | 412 MB        | "foobar_dev_12345"."fact_mobile_sends"                       | 57 MB      | 131 MB       | 189 MB
 foo_12345 | 412 MB        | "foobar_dev_12345"."fact_mobile_started"                      | 17 MB      | 39 MB        | 56 MB
 foo_12345 | 412 MB        | "foobar_dev_12345"."fact_mobile_stopped"                      | 16 MB      | 35 MB        | 51 MB
Run Code Online (Sandbox Code Playgroud)

我正在运行以下查询以获取表和索引大小。

SELECT
    table_catalog AS database_name,
    pg_size_pretty(pg_database_size(current_database())) As database_size,
    table_name,
    pg_size_pretty(table_size) AS table_size,
    pg_size_pretty(indexes_size) AS indexes_size,
    pg_size_pretty(total_size) AS total_size …
Run Code Online (Sandbox Code Playgroud)

postgresql performance postgresql-9.3 postgresql-performance

6
推荐指数
1
解决办法
3431
查看次数

如何在 VALUES 和 SELECT 之间选择 INSERT?

这个答案向我提出了如何在这样的函数之间VALUESSELECT中进行选择的问题。在 x86_64-unknown-linux-gnu 上使用PostgreSQL 9.4.3,由 gcc (Debian 4.9.2-10) 4.9.2, 64-bit 编译

CREATE OR REPLACE FUNCTION insaft_function()
   RETURNS TRIGGER AS
$func$
BEGIN     
   INSERT INTO file_headers (measurement_id, file_header_index_start
                                           , file_header_index_end)
   VALUES (NEW.measurement_id, TG_ARGV[0]::int, TG_ARGV[1]::int);

   RETURN NULL;  -- result ignored since this is an AFTER trigger
END
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

VALUES处理多行,但SELECT你可以做更多的事情。这里唯一的要求是对INSERT表格执行上述操作。您可以假设INSERT在系统的持续质量保证中每个周期完成100k 次这样的操作。

我注意到这些差异与我的数据不同,这里选择了三个中值:

VALUES
real      user      sys
-------------------------------
0m0.353s  0m0.256s  0m0.028s
0m0.327s  0m0.252s  0m0.036s
0m0.358s …
Run Code Online (Sandbox Code Playgroud)

postgresql trigger performance select postgresql-performance

6
推荐指数
1
解决办法
1322
查看次数

使用多个表中的列提高 order by 的性能

使用 PostgreSQL 8.4,我试图使用 order by 和两个表的索引列查询两个包含 100 万条记录的表,并且我正在失去性能(1 列需要 30 毫秒,两列需要 5 分钟)。例如:

select r.code, r.test_code, r.sample_code, s.barcode, s.registry_date
from requests r
inner join samples s on (s.code = r.sample_code)
order by s.barcode  asc , r.code asc
limit 21;
Run Code Online (Sandbox Code Playgroud)

表信息:

CREATE TABLE public.samples (
  code BIGINT NOT NULL,
  barcode VARCHAR(40) NOT NULL,
  registry_date TIMESTAMP WITH TIME ZONE NOT NULL,
  CONSTRAINT samples_pkey PRIMARY KEY(code)
);

CREATE INDEX idx_samp_barcode ON public.samples (barcode);
CREATE INDEX idx_samp_barcode_code ON public.samples (barcode, code);
CREATE INDEX …
Run Code Online (Sandbox Code Playgroud)

postgresql performance postgresql-8.4 recursive postgresql-performance

6
推荐指数
1
解决办法
2237
查看次数

使用左连接的慢 Postgresql 查询

我有一个关于 Postgres 的查询,我还添加了适当的索引。这里有什么遗漏吗?

SELECT orders.*, demo.name as d_name
FROM orders
LEFT JOIN users as demo ON demo.id = orders.dr_id
WHERE orders.customer_id = 526373 
AND (orders.log_id = 300)
AND (orders.order_count_id IN (10, 1, 8, 2, 3))
LIMIT 5
Run Code Online (Sandbox Code Playgroud)

查询计划来自EXPLAIN ANALYZE

QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit  (cost=2490.30..2867.15 rows=3 width=182) (actual time=33.292..34.115 rows=3 loops=1)
->  Nested Loop Left Join  (cost=2490.30..2867.15 rows=3 width=182) (actual time=33.291..34.113 rows=3 loops=1)
     ->  Bitmap Heap Scan on orders  (cost=2490.02..2842.22 rows=3 width=172) (actual time=33.279..34.097 rows=3 loops=1)
           Recheck Cond: ((customer_id …
Run Code Online (Sandbox Code Playgroud)

postgresql performance optimization postgresql-performance

6
推荐指数
0
解决办法
2636
查看次数

Postgres 的哪些查询比 MySQL InnoDB 更快

我已经阅读了相同架构/查询的 MySQL 和 PostgreSQL 之间的性能差异。以下是对文章的简要复述:

PostgreSQL 表是堆表(意味着没有聚集索引)......(Postgres)表的主键查找需要点击索引,查找文件中的位置,然后点击堆表并拉出记录。这意味着随机磁盘 I/O 的数量... InnoDB 使用不同的方法。使用 InnoDB,表是一个 b 树索引(聚集,物理排序)...... PK 查找所需的随机磁盘 I/O 更少......同时,索引扫描需要遍历两个索引而不是一个(index -> PK index -> table row ),这意味着使用主键以外的任何索引最终都会变慢,而顺序扫描仍然更慢。

哪种查询使用 Postgres 比使用 MySQL InnoDB 快得多?

我理解为什么 PK 查找对于 MySQL 来说要好得多。我不明白:

  1. 为什么通过两个索引(InnoDB,通过非 PK 索引查找)查找要慢得多?它是否需要两倍以上的 I/O 或 CPU?它可以弥补 PK 查找提升的巨大好处吗?
  2. 为什么 InnoDB 顺序扫描更慢?

PS Internet 说 Postgres 更适合复杂查询和子查询,但我仍然不明白为什么它更好?

mysql rdbms postgresql performance query-performance postgresql-performance

6
推荐指数
1
解决办法
3644
查看次数

永远不会完成的查询的日志计划

我们在每晚凌晨 2 点的负载中有一个更新,它有两次将 CPU 固定在 100% 并且在几个小时后从未完成。我强烈怀疑这是因为统计数据不准确导致连接中出现嵌套循环。我无法在具有相同硬件规格和 postgres 配置的较低环境中重现它。

我需要证明嵌套循环正在发生,然后才能放入 RFC 来解决问题(例如调整分析和自动真空设置)。我已经设置了 auto_explain 但这似乎只捕获了实际完成的查询的计划。如何为未完成的查询记录计划?

在 SQL Server 中,我可以通过使用 @get_plans=1 运行 sp_whoisactive 来做到这一点。我正在 Postgres 中寻找类似的东西。到目前为止,我唯一的想法是使用 cron 运行 EXPLAINs,但这似乎非常复杂。

postgresql performance postgresql-performance

6
推荐指数
1
解决办法
493
查看次数

多个相关表的全文搜索:索引和性能

我们有以下数据库结构

CREATE TABLE objects (
    id       int   PRIMARY KEY,
    name     text,
    address  text
);

CREATE TABLE tasks (
    id int           PRIMARY KEY,
    object_id int    NOT NULL,
    actor_id int     NOT NULL,
    description text
);

CREATE TABLE actors (
    id   int  PRIMARY KEY,
    name text
);
Run Code Online (Sandbox Code Playgroud)

用户输入以空格分隔的单词列表(基本上是搜索词),我们必须搜索满足以下条件的任务:如果每个搜索词在任务描述的串联中至少出现一次,则该任务是“匹配”,其关联对象的名称和地址以及关联参与者的名称。

现在,如果我们不关心性能,我们可以这样做(给定查询“foo bar”):

SELECT t.id, t.description
FROM tasks AS t
INNER JOIN actors AS a ON t.actor_id = a.id
INNER JOIN objects AS o ON t.object_id = o.id
WHERE to_tsvector(concat_ws(' ', t.description, o.name, o.address, a.name)) @@ …
Run Code Online (Sandbox Code Playgroud)

postgresql performance full-text-search postgresql-performance

6
推荐指数
2
解决办法
6365
查看次数

调整设置以减少 postgres 中大型查询的读取块数

使用 postgres 9.6,我不明白共享缓冲区如何与索引一起工作。

设置

  • Postgres 9.6
  • 所有默认设置
    • 共享缓冲区:128Mb
    • 工作内存:4Mb
    • 块大小:8192
    • ...

这意味着 shared_buffer 大小为 128 * 1024 * 1024 / 8192 = 16384 个块。

测试数据

我创建了一个简单的表,其中包含随机数据和每列的索引。

DROP TABLE IF EXISTS sandbox;


CREATE TABLE sandbox AS
SELECT generate_series(1, 4000000) AS pk,
       random() AS x;

CREATE INDEX ON sandbox(pk);
CREATE INDEX ON sandbox(x);
Run Code Online (Sandbox Code Playgroud)

我去了 4M 行。这是表和索引占用的大小:

postgres=# SELECT relname AS "relation",
       pg_relation_size(C.oid) / 8192 AS "blocks",
       pg_size_pretty(pg_relation_size(C.oid)) AS "size"
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE relname …
Run Code Online (Sandbox Code Playgroud)

postgresql performance postgresql-performance

6
推荐指数
1
解决办法
1849
查看次数

你能减慢对 postgres 数据库中特定用户的查询吗

我假设可以减慢 postgres 数据库中特定用户的查询访问速度。你会怎么做?有没有办法让用户看到这样的设置已经被放置在他们身上,以及用户可以做些什么来克服它,如果有的话。

基本上我有兴趣在每个用户的基础上限制资源以防止不良行为者滥用系统。

postgresql performance postgresql-performance

6
推荐指数
1
解决办法
1459
查看次数

如何加快查询时间序列中的最后一个值?

prices在 PostgreSQL 10 DB 中有一个时间序列表。
这是一个简化的测试用例来说明问题:

CREATE TABLE prices (
    currency text NOT NULL,
    side     boolean NOT NULL,
    price    numeric NOT NULL,
    ts       timestamptz NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

我想快速查询每个currency/side双人组的最后一个值,因为这会给我每种货币的当前买入/卖出价格。

我目前的解决方案是:

create index on prices (currency, side, ts desc);

select distinct on (currency, side) *
 order by currency, side, ts desc;
Run Code Online (Sandbox Code Playgroud)

但这会让我在这个只有 ~30k 行的表中查询非常(~500ms)。

实际的表都有,我想组四列而不是两个。下面是实际的表和查询的样子:

create table prices (
    exchange integer not null,
    pair text not null,
    side …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index-tuning greatest-n-per-group postgresql-10 postgresql-performance

6
推荐指数
1
解决办法
1144
查看次数