标签: postgresql-performance

为什么 PostgreSQL 不使用我的索引在某些排序规则下进行文本前缀搜索?

考虑:

create table tab (foo text not null);
create index tab_ix_foo on tab(foo);

select * from tab where foo like 'pre%';
Run Code Online (Sandbox Code Playgroud)

Postgres 不使用索引来执行该搜索。使用排序规则时"POSIX",Postgres 使用索引:http://sqlfiddle.com/#!12/ed1cc /1

使用排序规则时"en_US",Postgres 使用顺序扫描:http://sqlfiddle.com/#!12 /efb18/1

为什么有区别?

postgresql indexing prefix postgresql-9.2 postgresql-performance

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

优化大表最新行的查询性能

我有一张大桌子:

CREATE TABLE "orders" (
"id" serial NOT NULL,
"person_id" int4,
"created" int4,
CONSTRAINT "orders_pkey" PRIMARY KEY ("id")
);
Run Code Online (Sandbox Code Playgroud)

90% 的请求与 过去 2-3 天的订单有关person_id,例如:

select * from orders
where person_id = 1
and created >= extract(epoch from current_timestamp)::int - 60 * 60 * 24 * 3;
Run Code Online (Sandbox Code Playgroud)

我怎样才能提高性能?

我了解分区,但是现有行呢?看起来我需要INHERITS每 2-3 天手动创建一次表。

sql postgresql indexing performance postgresql-performance

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

在 Postgres 中查找以空格分隔的字符串

character varying在 postgres 中有一个字段,其中包含一组以 1 个空格分隔的字符串。例如:

  • --> one two three <--
  • --> apples bananas pears <--

我放置--><--显示字符串开始和结束的位置(它们不是存储字符串本身的一部分)

我需要查询此字段以查明整个字符串是否包含某个单词(例如 apple)。一个可能的查询是

SELECT * FROM table WHERE thefield LIKE '%apple%'
Run Code Online (Sandbox Code Playgroud)

但它很糟糕并且不会扩展,因为 b-tree 索引仅在模式附加到字符串的开头时才扩展,而在我的情况下,搜索的字符串可以定位在字段中的任何位置。

你建议如何解决这个问题?

postgresql indexing database-design pattern-matching postgresql-performance

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

PostgreSQL autovacuum 导致性能显着下降

我们的 Postgres 数据库(托管在具有 1 个 CPU、3.7 GB RAM 的 Google Cloud SQL 上,见下文)主要由一个大约 90GB 的大表组成,大约有大约 6000 万行。使用模式几乎完全由附加和靠近表末尾的一些索引读取组成。有时会删除一些用户,删除散布在表中的一小部分行。

这一切正常,但每隔几个月就会在该表上触发自动清理,这会显着影响我们服务的性能约 8 小时:

  • 在 autovacuum 期间(几个小时),存储使用量增加了约 1GB,然后慢慢恢复到以前的值(由于 autovacuum 释放页面,最终可能会低于它)
  • 数据库 CPU 利用率从 <10% 跃升至 ~20%
  • 磁盘读/写操作从接近零增加到约 50/秒
  • 数据库内存略有增加,但保持在 2GB 以下
  • 正如预期的那样,事务/秒和入口/出口字节也相当不受影响

这会在 autovacuum 期间将我们服务的第 95 个延迟百分位数从 ~100ms 增加到 ~0.5-1s,从而触发我们的监控。该服务每秒处理大约 10 个请求,每个请求由一些简单的 DB 读/写组成,每个请求的延迟通常为 2-3 毫秒。

以下是一些说明问题的监控屏幕截图:

CPU使用率 存储使用 内存使用情况 读/写操作 潜伏

数据库配置相当普通:

数据库配置

记录此 autovacuum 过程的日志条目如下所示:

system usage: CPU 470.10s/358.74u sec elapsed 38004.58 sec
avg read rate: 2.491 MB/s, avg write rate: 2.247 MB/s
buffer usage: 8480213 hits, 12117505 …
Run Code Online (Sandbox Code Playgroud)

postgresql google-cloud-sql postgresql-performance autovacuum

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

这个 PostgreSQL UPDATE 查询偶尔需要几个小时才能完成运行的原因是 autovacuum (VACUUM) 吗?

这个 sql 查询通常只需要几分钟就可以运行:

update import_parts ip
set part_manufacturer_id = pslc.part_manufacturer_id
from parts.part_supplier_line_codes pslc
where trim(lower(ip.line_code)) = trim(lower(pslc.supplier_line_code))
and (ip.status is null or ip.status != '6')
and ip.distributor_id = pslc.distributor_id
and ip.distributor_id = 196;
Run Code Online (Sandbox Code Playgroud)

但我注意到它有时会卡住并被 2 小时的 statement_timeout 自动取消。我注意到有几次,当它卡住时,autovacuum 正在运行,autovacuum 也需要很长时间才能完成运行。这是更新查询和 autovacuum 都在运行的一个实例,它们都需要很长时间才能完成运行:

自动真空和更新查询

^ 在这种情况下,autovacuum 在大约一个小时内完成运行,而更新查询在近 2 小时内完成运行。在其他情况下,更新查询超过 2 小时 statement_timeout,因此它会自动取消。

现在我的问题是,autovacuum (VACUUM) 是更新查询卡住或需要数小时才能完成运行的原因吗?如果是,我该怎么做才能防止更新查询卡住或变得如此缓慢?如果不是,您认为是什么导致更新查询卡住或变得如此缓慢?

我们使用的是 PostgreSQL 9.6.15

更新 1

我检查了我们的 RDS 实例是否耗尽了服务器资源。我们的实例大小是 db.t2.medium(2 个 vCPU,4GB RAM,1000 IOPS,存储类型为 iops SSD)。

这是过去 3 天的 cloudwatch 指标。请注意,在过去 3 天内,上面的更新 sql 查询卡住了多次。

cpu利用率

可释放内存

写iops

更新 2

更新查询和 …

postgresql vacuum postgresql-performance

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

结合其他列对 JSONB 键建立索引

为了搜索jsonb列中的特定键,我想在该列上创建索引。

使用:Postgres 10.2

忽略一些不相关的列,我有包含animals这些列的表(省略一些不相关的列):

animalid PK number
location (text)
type (text)
name (text)
data (jsonb) for eg: {"age": 2, "tagid": 11 }
Run Code Online (Sandbox Code Playgroud)

我需要根据:locationtype和进行搜索tagId。喜欢:

where location = ? and type = 'cat' and (data ->> 'tagid') = ?
Run Code Online (Sandbox Code Playgroud)

其他要点:

  • 只有猫类型的动物才会有标签 ID,这是现在添加的新动物类型。
  • 与其他类型的动物相比,整个表中“猫”的数量会更少。
  • 该表很大,有数百万行并且已分区。

如何确保搜索速度快?我考虑过的选项:

  1. 创建一个单独的表 cats 来存储:animal_id, location, tagId(尽管无法 FK 到分区父表)
  2. location在和typejsonb 键上创建索引。
  3. 创建一个新的(索引)列tagId- 对于除猫之外的所有动物,该列将为空。

我确实在表上的其他列上有一个索引 - 但对如何创建索引以基于快速搜索猫有点困惑tagid。有什么建议么?

更新 …

postgresql indexing database-design postgresql-performance jsonb

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

PostgreSQL为什么不在小表上使用索引?

我在PostgreSQL中有下表:

CREATE TABLE index_test
(
    id int PRIMARY KEY NOT NULL,
    text varchar(2048) NOT NULL,
    last_modified timestamp NOT NULL,
    value int,
    item_type varchar(2046)
);
CREATE INDEX idx_index_type ON index_test ( item_type );
CREATE INDEX idx_index_value ON index_test ( value )
Run Code Online (Sandbox Code Playgroud)

我进行以下选择:

explain select * from index_test r where r.item_type='B';
explain select r.value from index_test r where r.value=56;
Run Code Online (Sandbox Code Playgroud)

执行计划的解释如下:

在index_test r上进行序列扫描(成本= 0.00..1.04行= 1宽度= 1576)
    过滤器:(((item_type):: text ='B':: text)'

据我了解,这是一个全表扫描。问题是:为什么不使用我的索引?

可能是因为表中的行太少了?我只有二十个。您能否为我提供一条SQL语句,以便用随机数据轻松填充我的表以检查索引问题?

我发现了这篇文章:http : //it.toolbox.com/blogs/db2luw/how-to-easily-populate-a-table-with-random-data-7888,但它对我不起作用。语句的效率并不重要,只有简单性。

sql postgresql postgresql-performance

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

在WITH子句中添加无关表是否会减慢PostgreSQL中的查询速度?

我有一个(可能)基本问题,关于Postgres如何执行包含WITH子句的查询.我想知道在WITH子句中包含多余的表是否会减慢查询速度.也就是说,如果在WITH子句中创建的"临时"表永远不会在子句之外调用WITH,那么实际创建的是"临时"表吗?

在第一个例子中,我正在加入两个使用WITH子句创建的"临时"表:

--Example 1
WITH temp1 as (
SELECT * from table_1
),
temp2 as (
select * from table_2
)
select * 
from temp1
join temp2;
Run Code Online (Sandbox Code Playgroud)

在第二个例子中,我正在执行完全相同的查询,除了在WITH子句中创建了一个无关的表"temp3" .

--Example 2
WITH temp1 as (
SELECT * from table_1
),
temp2 as (
select * from table_2
),
temp3 as (
select * from table_3
)
select * 
from temp1
join temp2;
Run Code Online (Sandbox Code Playgroud)

这两个查询之间有任何性能差异吗?如果table_3是一个巨大的表,这会减慢示例2与示例1中的查询吗?如果没有,为什么不呢?

好像它不会影响查询时间.我仍然很好奇为什么,尽管......

sql postgresql common-table-expression postgresql-performance

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

如果在该字段上构建b-tree索引,PostgreSQL如何执行ORDER BY?

我有一张桌子bsort:

CREATE TABLE bsort(a int, data text);
Run Code Online (Sandbox Code Playgroud)

这里data可能不完整.换句话说,一些元组可能没有data价值.

然后我在表上构建一个b树索引:

CREATE INDEX ON bsort USING BTREE(a);
Run Code Online (Sandbox Code Playgroud)

现在,如果我执行此查询:

SELECT * FROM bsort ORDER BY a;
Run Code Online (Sandbox Code Playgroud)

PostgreSQL是否使用nlogn复杂性对元组进行排序,还是直接从b-tree索引获取顺序?

sorting postgresql indexing sql-order-by postgresql-performance

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

快速计算不同列值的方法(使用索引吗?)

问题:查询花费的时间太长

我有一个新表,看起来像这样,有3e6行:

CREATE TABLE everything_crowberry (
    id             SERIAL  PRIMARY KEY,
    group_id       INTEGER,
    group_type     group_type_name,
    epub_id        TEXT,
    reg_user_id    INTEGER,
    device_id      TEXT,
    campaign_id    INTEGER,
    category_name  TEXT,
    instance_name  TEXT,
    protobuf       TEXT,
    UNIQUE (group_id, group_type, reg_user_id, category_name, instance_name)
);
Run Code Online (Sandbox Code Playgroud)

对于我的上下文,这通常是有意义的,并且大多数查询的速度都可以接受。

但是这样的查询不是很快:

analytics_staging=> explain analyze select count(distinct group_id) from everything_crowberry;
                                                               QUERY PLAN                                                               
----------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=392177.29..392177.30 rows=1 width=4) (actual time=8909.698..8909.699 rows=1 loops=1)
   ->  Seq Scan on everything_crowberry  (cost=0.00..384180.83 rows=3198583 width=4) (actual time=0.461..6347.272 rows=3198583 loops=1)
 Planning time: 0.063 ms
 Execution time: 8909.730 ms
(4 rows)

Time: 8910.110 …
Run Code Online (Sandbox Code Playgroud)

sql postgresql distinct postgresql-performance postgresql-9.5

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