performance - Postgres 主键 'less than' 运行缓慢

标签 performance postgresql indexing

考虑下表

CREATE TABLE COMPANY(
   ID BIGINT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

如果我们在这个表中有 1 亿个随机数据。

Select age from company where id=2855265

在不到一毫秒内执行

Select age from company where id<353

返回少于 50 行并在不到一毫秒内执行

两个查询都使用索引

但是下面的查询使用了全表扫描并在3秒内执行完毕

Select age from company where id<2855265

返回少于 500 行

如何加快选择主键小于变量的查询?

最佳答案

性能

谓词id < 2855265可能会返回表中的大部分行。除非 Postgres 的表统计信息预计只有大约 500 行,否则它可能会从索引扫描切换到位图索引扫描,甚至是顺序扫描.说明:

我们需要查看 EXPLAIN (ANALYZE, BUFFERS) 的输出为您的查询。

当您重复查询时,是否获得相同的性能?可能存在缓存效应。

无论哪种方式,对于 500 行,3 秒都是减慢的方式,Postgres 可能正在处理过时或不准确的表统计信息。或者您的服务器配置可能存在问题(资源不足)。或者可能有其他几个不太常见的原因,包括硬件问题......

如果VACUUM ANALYZE没有帮助,VACUUM FULL ANALYZE可能。它在原始状态下有效地重写了整个表和所有索引。对表进行独占锁定,可能与并发访问冲突!

我还会考虑增加 id 的统计目标柱子。说明:


表定义?

无论您做什么,您的表定义似乎都存在各种问题:

CREATE TABLE COMPANY(
   ID BIGINT PRIMARY KEY NOT NULL,  -- int is probably enough. "id" is a terrible column name
   NAME      TEXT    NOT NULL,  -- "name" is a teriible column name
   AGE       INT     NOT NULL,  -- typically bad idea to store age, store birthday instead
   ADDRESS   CHAR(50),   -- never use char(n)!
   SALARY    REAL        -- why would a company have a salary? never store money as real
);

你可能想要这样的东西:

CREATE TABLE emmployee(
   emploee_id    serial PRIMARY KEY
   company_id    int NOT NULL  -- REFERENCES company(company_id)?
 , birthday      date NOT NULL
 , employee_name text NOT NULL
 , address       varchar(50)   -- or just text
 , salary        int           -- store amount as *Cents*
);

相关:

关于performance - Postgres 主键 'less than' 运行缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41470221/

相关文章:

IE11 上的 Angular 4 性能/CPU 使用率

sql-server - 通过在 Always on 可用性组节点上负载平衡 SQL 查询来提高应用程序性能?

sql - 左连接和 count() 缺少行所需的解释

mysql - 如何强制 Mysql 在 IN 子句中使用主索引...?

C# 枚举索引问题

python - 两种相似方法之间获取可迭代长度的时间差

用户 friend 的 Php 爆炸或唯一 Mysql 表?

django - 如何在 Django 模板中使用 IntegerRangeField

json - 将 JSON 迁移到 HSTORE

java - neo4j - 属性自动索引器不存储值