相关疑难解决方法(0)

使用 ORDER BY 日期和文本优化简单查询

我有一个基于日期字段和数字字段的订单查询 Postgres 中的表,该表有 1000000 条记录

表的数据类型为:

fcv_id = serial
fcv_fecha_comprobante = timestamp without time zone
fcv_numero_comprobante = varchar(60)
Run Code Online (Sandbox Code Playgroud)

查询是:

SELECT fcv_id, fcv_fecha_comprobante FROM factura_venta
ORDER BY fcv_fecha_comprobante, fcv_numero_comprobante
Run Code Online (Sandbox Code Playgroud)

这个查询大约需要 5 秒,但如果我取出“order by”,查询只需要 0.499 秒

我遇到的问题是我需要在尽可能短的时间内运行这个查询,所以我在谷歌上搜索我可以做什么并使用以下查询创建一个复合索引

CREATE INDEX factura_venta_orden ON factura_venta
USING btree (fcv_fecha_comprobante ASC NULLS LAST
           , fcv_numero_comprobante ASC NULLS LAST);
ALTER TABLE factura_venta CLUSTER ON factura_venta_orden;
Run Code Online (Sandbox Code Playgroud)

但是查询花费的时间相同甚至更多。

我使用的是 Postgres 9.0.13,这里是 73436 行的 EXPLAIN

Sort  (cost=11714.03..11897.62 rows=73436 width=27) (actual time=1260.759..1579.853 rows=73436 loops=1)
  Sort Key: fcv_fecha_comprobante, fcv_numero_comprobante
  Sort Method:  external merge …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index query-performance

4
推荐指数
2
解决办法
6348
查看次数

4300 万张 PostgreSQL 表上的复合索引

这个问题与我之前问过的问题有关:PostgreSQL 中复合索引中的列顺序(和查询顺序)

我想我可以在这里尖锐和限制我的问题,而不是超载这个问题。鉴于以下查询(和 EXPLAIN ANALYZE),我正在创建的复合索引有帮助吗?

第一个查询仅使用简单索引(大纲上的 GIST)和(pid 上的 BTREE)运行。

查询是:

EXPLAIN ANALYZE SELECT DISTINCT ON (path) oid, pid, product_name, type, path, size 
FROM portal.inventory AS inv 
WHERE ST_Intersects(st_geogfromtext('SRID=4326;POLYGON((21.51947021484375 51.55059814453125, 18.9129638671875 51.55059814453125, 18.9129638671875 48.8287353515625, 21.51947021484375 48.8287353515625, 21.51947021484375 51.55059814453125))'), inv.outline) 
AND (inv.pid in (20010,20046)) 
Run Code Online (Sandbox Code Playgroud)

——

结果如下(速度更快,但也许这只是因为数据库是热的)。

"Unique  (cost=581.76..581.76 rows=1 width=89) (actual time=110.436..110.655 rows=249 loops=1)"
"  ->  Sort  (cost=581.76..581.76 rows=1 width=89) (actual time=110.434..110.477 rows=1377 loops=1)"
"        Sort Key: path"
"        Sort Method: quicksort  Memory: 242kB"
"        ->  Bitmap Heap Scan on inventory …
Run Code Online (Sandbox Code Playgroud)

postgresql index index-tuning

4
推荐指数
1
解决办法
535
查看次数

优化对两个大表的查询

我的系统中有一个非常重要的查询,由于表上的数据量很大,执行时间太长。我是一名初级 DBA,我需要为此进行最佳优化。每个表大约有 8000 万行。

表是:

tb_pd

   Column            |  Type   | Modifiers | Storage | Stats target | Description 
---------------------+---------+-----------+---------+--------------+-------------
 pd_id               | integer | not null  | plain   |              | 
 st_id               | integer |           | plain   |              | 
 status_id           | integer |           | plain   |              | 
 next_execution_date | bigint  |           | plain   |              | 
 priority            | integer |           | plain   |              | 
 is_active           | integer |           | plain   |              | 
Indexes:
    "pk_pd" PRIMARY KEY, btree (pd_id)
    "idx_pd_order" btree (priority, next_execution_date) …
Run Code Online (Sandbox Code Playgroud)

postgresql optimization index-tuning query-performance

4
推荐指数
1
解决办法
5466
查看次数

OR 运算符的索引:a=x 或 b=x

我有一个包含三个整数列ida的表b
我想获取所有记录,其中ab匹配指定参数排序id

select id, a, b from t where a=x or b=x order by id
Run Code Online (Sandbox Code Playgroud)

请注意,和 的x值相同。ab

这里最合适的索引是什么?

更新:我们总是在列和中寻找相同的值,这一事实有什么用处吗?我们可以为此创建一个表达式索引吗?ab

postgresql performance index postgresql-performance

4
推荐指数
1
解决办法
928
查看次数

从 N:M 关系中获取给定组的成员

我有这种 N:M 关系:

CREATE TABLE auth_user (
    id integer NOT NULL PRIMARY KEY,
    username character varying(150) NOT NULL UNIQUE
);

CREATE TABLE auth_group (
    id integer NOT NULL PRIMARY KEY,
    name character varying(80) NOT NULL UNIQUE
);

CREATE TABLE auth_user_groups (
    id integer NOT NULL PRIMARY KEY,
    user_id integer REFERENCES auth_user(id) NOT NULL,
    group_id integer REFERENCES auth_group(id) NOT NULL,
    CONSTRAINT user_groups UNIQUE(user_id, group_id)
);

INSERT INTO auth_user VALUES (1, 'user1');
INSERT INTO auth_user VALUES (2, 'user2');
INSERT INTO auth_group VALUES …
Run Code Online (Sandbox Code Playgroud)

postgresql join many-to-many

4
推荐指数
2
解决办法
292
查看次数

PostgrSQL 中大表的预缓​​存索引

我有一个包含大约 1000 万行的表,其中包含一个主键和一个定义在其上的索引:

create table test.test_table(
    date_info date not null,
    string_data varchar(64) not null,
    data bigint
    primary key(date_info, string_data));
    create index test_table_idx 
    on test.test_table(string_data);
Run Code Online (Sandbox Code Playgroud)

我有一个使用了的查询test_table_idx

select distinct date_info from test.test_table where string_data = 'some_val';
Run Code Online (Sandbox Code Playgroud)

问题是第一次运行查询最多可能需要 20 秒,而在任何后续运行中都需要 < 2 秒。

有没有办法将整个索引加载到内存中,而不是在第一次访问时获取数据库加载信息?

postgresql index cache postgresql-12

4
推荐指数
1
解决办法
425
查看次数

这里有什么更好的 - 单列或多列主键?

假设您有一张桌子groups和一张桌子item。每个项目都属于一个组。它是该群体的固有组成部分。一个项目不能存在于一个组之外,也不能移动到另一个组中。

当试图决定item表的主键时,我应该使用什么?

我应该像这样组成一个人工全局序列键:

CREATE TABLE items
(
    item serial PRIMARY KEY,
    group integer NOT NULL REFERENCES groups(group),
);
Run Code Online (Sandbox Code Playgroud)

...或者我应该使用复合键和每组项目序列,如下所示:

CREATE TABLE items
(
    group integer NOT NULL REFERENCES groups(group),
    item integer NOT NULL,

    PRIMARY KEY(group, item)
);
Run Code Online (Sandbox Code Playgroud)

我更倾向于第二种解决方案的原因是帖子 URL 将始终显示组项目,因此将它们都作为复合主键是有意义的。在第一种解决方案的情况下,URL 包含多余的信息,因为组 ID 已经可以单独从项目 ID 中推导出来。但是,URL 结构是给定的,不能更改。

第二种解决方案的缺点是您必须管理每个组的序列(即每个组的每个项目整数应从 0 开始)。

在最佳实践、规范化和性能方面哪个更好?或者这只是品味问题?

postgresql database-design best-practices primary-key

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

有效地从 am:n 表中返回两个聚合数组

我有一个表,用于表上的多对多关系users来表示用户之间的跟随关系:

CREATE TABLE users (
    id text PRIMARY KEY,
    username text NOT NULL
);

CREATE TABLE followers (
    userid text,
    followid text,
    PRIMARY KEY (userid, followid),
    CONSTRAINT followers_userid_fk   FOREIGN KEY (userid)   REFERENCES users (id),
    CONSTRAINT followers_followid_fk FOREIGN KEY (followid) REFERENCES users (id)
);

CREATE INDEX followers_followid_idx ON followers (followid);
Run Code Online (Sandbox Code Playgroud)

当我想使用与用户相关的数据创建 JSON 响应时,我有两种情况:

  • 通过 id 请求单个用户,
  • 通过 id 列表请求用户对象数组

用户数据对象应包含两个用户 ID 数组,一个是他们关注的用户,另一个是关注他们的用户。为了创建这两个字段,我使用了以下SELECT语句。

DECLARE follows RECORD;
SELECT  array (select followid FROM followers where userid = Puserid) AS following, …
Run Code Online (Sandbox Code Playgroud)

postgresql performance view many-to-many postgresql-10

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

PostgreSQL 查询成本高

我有一个包含超过 10.000.000 条记录的表,并且我正在创建一个返回大约 4436 条记录的查询。

碰巧它给我的印象是获取最后一条记录的查询成本非常高。

Index Scan using idx_name on task  (cost=0.28..142102.57 rows=3470 width=34) (actual time=14.690..22.894 rows=4436 loops=1)
"  Index Cond: ((situation = ANY ('{0,1,2,3,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}'::integer[])) AND (deadline < CURRENT_TIMESTAMP))"
Planning Time: 1.335 ms
JIT:
  Functions: 5
  Options: Inlining false, Optimization false, Expressions true, Deforming true
  Timing: Generation 1.654 ms, Inlining 0.000 ms, Optimization 1.214 ms, Emission 13.163 ms, Total 16.030 ms
Execution Time: 24.758 ms
Run Code Online (Sandbox Code Playgroud)

这个成本水平是否可以接受,或者这个指标是否需要改进?

指数:

CREATE INDEX idx_name ON task (situation, deadline, approved)
WHERE
deadline IS NOT …
Run Code Online (Sandbox Code Playgroud)

postgresql postgresql-12 postgresql-performance

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

约束排除以获取最新的 N 行

我正在管理一个包含几百万条记录的表,这些记录被实时插入。我的应用程序的一部分需要显示最后插入的 N 行,所以一开始我只是查询:

select id, logdate, content from measurements order by logdate DESC limit 500;
Run Code Online (Sandbox Code Playgroud)

几天后,我发现设置id为(对于此示例)更快10000000000 - extract(epoch from logdate),并将其用作PRIMARY KEY,所以

select id, date, content from measurements limit 500;
Run Code Online (Sandbox Code Playgroud)

自然会按 排序id,因此会产生最新的记录。

随着表的增长,它变得难以管理,所以我求助于分区。我按照文档说的那样做了

CREATE TABLE measurement_y2007m11 (
CHECK ( logdate >= DATE '2007-11-01' AND logdate < DATE '2007-12-01' )
) INHERITS (measurement);

CREATE TABLE measurement_y2007m12 (
CHECK ( logdate >= DATE '2007-12-01' AND logdate < DATE '2008-01-01' )
) INHERITS (measurement); …
Run Code Online (Sandbox Code Playgroud)

postgresql index partitioning

0
推荐指数
1
解决办法
243
查看次数