我似乎在中型 RDS 盒子(db.m3.medium,3.7gb ram)上的查询速度很慢。
这是一个包含 4,152,928 行的表格。
select sum(some_field) c
from pages
where pages.some_id=123
and pages.first_action_at > '2014-01-01 00:00:00 +1000'
Run Code Online (Sandbox Code Playgroud)
总运行时间:45031 毫秒。
在本地,我有大约 110 万行,同样的查询需要大约 450 毫秒。
这是查询计划,来自解释:
Aggregate (cost=475640.59..475640.60 rows=1 width=4)
-> Seq Scan on pages (cost=0.00..475266.07 rows=149809 width=4)
Filter: ((first_action_at > '2014-01-01 00:00:00'::timestamp without time zone)
AND (some_id = 447))
Run Code Online (Sandbox Code Playgroud)
这是来自解释分析的回应:
Aggregate (cost=475641.74..475641.76 rows=1 width=4) (actual time=42419.717..42419.718 rows=1 loops=1)
-> Seq Scan on pages (cost=0.00..475267.22 rows=149810 width=4) (actual time=0.013..42265.908 rows=141559 loops=1)
Filter: ((first_action_at > '2014-01-01 00:00:00'::timestamp without time …Run Code Online (Sandbox Code Playgroud) postgresql performance index index-tuning postgresql-performance
我有一个带有主表和 2 个子表的 PostgreSQL 数据库。我的主表:
CREATE TABLE test (
id serial PRIMARY KEY,
date timestamp without time zone
);
CREATE INDEX ON test(date);
Run Code Online (Sandbox Code Playgroud)
我的子表:
CREATE TABLE test_20150812 (
CHECK ( date >= DATE '2015-08-12' AND date < DATE '2015-08-13' )
) INHERITS (test);
CREATE TABLE test_20150811 (
CHECK ( date >= DATE '2015-08-11' AND date < DATE '2015-08-12' )
) INHERITS (test);
CREATE INDEX ON test_20150812(date);
CREATE INDEX ON test_20150811(date);
Run Code Online (Sandbox Code Playgroud)
当我执行查询时:
select * from test_20150812 where date > '2015-08-12' order …Run Code Online (Sandbox Code Playgroud) postgresql performance index partitioning inheritance postgresql-performance
我遇到了一个问题,SELECT查询很慢,因为当最终结果的数量为 0并且LIMIT指定了一个子句时,它不使用索引。
如果结果数大于 0,则 Postgres 使用索引并在 ~ 1ms 内返回结果。据我所知,这似乎总是正确的。
如果结果数为 0 且没有LIMIT使用,则 Postgres 使用索引,结果在 ~ 1ms 内返回
如果结果数为 0 并且LIMIT指定了 a,则 Postgres 会执行顺序扫描,结果大约需要 13,000 毫秒。
为什么 PostgreSQL 在最后一种情况下不使用索引?
基数:
总计约 2100 万行。
~ 300 万行WHERE related_id=1
~ 300 万行WHERE related_id=1 AND platform=p1
2 行WHERE related_id=1 AND platform=p2
0 行WHERE related_id=1 AND platform=p3
~ 800 万行WHERE platform=p2
Postgres 版本:9.4.6
表架构:
CREATE TYPE platforms AS ENUM ('p1', …Run Code Online (Sandbox Code Playgroud) postgresql performance index statistics postgresql-9.4 postgresql-performance
实际查询更多,但我面临的问题可以归结为:
用于过滤单调递增整数行集的查询,以便 -在最终结果集中, row(n+1).value >= row(n).value + 5。
对于我需要解决的实际问题,行集计数在 1000 秒内。
举几个例子来澄清:
我设法通过以下查询获得了所需的结果,但它似乎过于复杂。取消注释不同的“..with t(k)..”以尝试它们。
我正在寻找任何简化或替代方法来获得相同的结果。
with recursive r(n, pri) as (
with t(k) as (values (1),(2),(3),(4),(5)) -- the data we want to filter
-- with t(k) as (values (1),(5),(7),(10),(11),(12),(13))
-- with t(k) as (values (6),(8),(11),(16),(20),(23))
-- with t(k) as (values (6),(8),(12),(16),(20),(23))
select min(k), 1::bigint from t -- bootstrap for recursive processing. 1 here represents rank().
UNION
select k, (rank() over(order …Run Code Online (Sandbox Code Playgroud) 我有一个场景,我需要运行工资报告。该报告计算特定日期范围内按员工分组的工资金额。
例如,当运行 2016-11-01 到 2016-11-30 的报告时,我会看到以下结果:
Staff Id Total
------------------
1 123.00
2 439.22
Run Code Online (Sandbox Code Playgroud)
我对上述报告使用以下查询:
select
user_id as staff_id,
sum(amount) as total
from transaction
where
business_id = <business_id> and
type = 'staff' and
kind = 'commission' and
created_at between <start_date> and <end_date>
group by
user_id;
Run Code Online (Sandbox Code Playgroud)
我正在尝试根据以下要求确定优化此查询性能的最佳方法:
business_id、start_date和end_date看来视图和函数都可以完成这项工作,但我并不能 100% 确定哪种方法是考虑到需求的最佳方法。
旁注:如果能够根据上面提到的参数来缓存数据就太好了,但是数据库方面似乎没有很好的解决方案。如我错了请纠正我!
附加信息:
business_id、type、kind和列上有索引。这些都是单列、btree 索引。user_idcreated_attransaction在单个事务的多个表中插入大量或行(数百万)所产生的额外成本是多少?
是否可以做一些事情(调整参数),以便在单个事务中大量插入的成本接近在自动提交中进行的成本?
如果我在 Postgres 表中有一堆行,然后创建一个索引,如果在创建后插入新数据行,索引是否会自动更新?
或者说,REINDEX 是仅在一些罕见的情况下需要,还是在添加新数据时才需要?
我们在 PostgreSQL 的单个事务中执行大约 100k DDL 语句。在执行过程中,各个 Postgres 连接的内存使用量逐渐增加,一旦它无法获得更多内存(在 3GB 内存上从 10MB 使用量增加到 2.2GB),OOM 杀手用 9 命中它,导致 Postgres 进入恢复模式.
BEGIN;
CREATE SCHEMA schema_1;
-- create table stmts - 714
-- alter table add pkey stmts - 714
-- alter table add constraint fkey stmts - 34
-- alter table add unique constraint stmts - 2
-- alter table alter column set default stmts - 9161
-- alter table alter column set not null stmts - 2405
-- alter table add check …Run Code Online (Sandbox Code Playgroud) postgresql performance transaction ddl postgresql-9.6 postgresql-performance
当一次只能进行一个引用时,我正在寻找在一个表中引用多个表的最有效方法。这意味着表 A 和 B 被表 C 引用,但 A 和 B 不能在 C 的一行中引用,并且我在编写查询时选择要查看的表。
我考虑过 4 种方法:
type和一个列FK,这样我就可以进行像这样的连接type = 'A' AND a.pk = c.a_fk(这就是我们现在使用的)FROM c JOIN a ON a.d_fk = c.d_fk在我尝试的每个解决方案中,查询规划器对于将返回多少行的判断都是错误的。
这是一个例子:我创建了一个简单的数据库,其中有 3 个表,如下所示:
Table "public.a"
Column | Type | Collation | Nullable | Default
--------+--------+-----------+----------+-------------------------------
pk | bigint | | not null | …Run Code Online (Sandbox Code Playgroud) postgresql performance database-design postgresql-9.6 postgresql-11 postgresql-performance
我计划将包含更多 1000 万条记录的 CSV 加载到 PostgreSQL v12.1,其中一列具有“分类”值,因此为其创建枚举类型似乎是一个不错的选择,但它包含 208 个类别。
最短的字段为 2,最长的字段为 11 个字符。所有字段的平均值为 2.4。字符编码是 UTF8,但所有字符都是 ASCII。
我应该使用enumerated或varchar哪种类型?
我丢弃char是因为官方 PostgreSQL 文档说明了有关char、varchar和text 的以下内容:
提示:这三种类型之间没有性能差异,除了使用空白填充类型时增加了存储空间,以及在存储到长度受限列时需要额外的一些 CPU 周期来检查长度。虽然 character(n) 在其他一些数据库系统中具有性能优势,但在 PostgreSQL 中没有这样的优势;事实上 character(n) 通常是三个中最慢的,因为它有额外的存储成本。在大多数情况下,应改用文本或字符变化。
PostgreSQL 中的枚举值在磁盘上占用4 个字节(请参阅 8.7.4. 实现细节)。考虑到这一点和使用enum类型的2.4 平均字符串长度会导致磁盘使用率略高(PostgreSQL 中的短字符串需要一个额外的字节磁盘空间)。我仍然有一种直觉,即使用 enum 是更好的选择,因为它的实现使许多针对它的操作更快。
performance ×10
postgresql ×10
index ×3
cte ×1
ddl ×1
import ×1
index-tuning ×1
inheritance ×1
partitioning ×1
recursive ×1
statistics ×1
transaction ×1