sql—是否可以对枚举进行索引?

2ul0zpep  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(663)

问题实际上是关于sql查询的优化。假设我们已经定义了这个表。

CREATE TYPE record_type AS ENUM (
  'TRANSFER',
  'TRADE',
  'VOUCHER'
);

CREATE TYPE record_status AS ENUM (
  'NEW',
  'VALIDATED',
  'EXPIRED'
);

CREATE TABLE good_records (
  id uuid PRIMARY KEY,
  user_id uuid NOT NULL,
  type record_type NOT NULL,
  status record_status NOT NULL,
  amount numeric(36,18) NOT NULL DEFAULT 0,
  expired_at timestamp WITH TIME ZONE NOT NULL,
  notification_sent boolean DEFAULT false,
);

我想每10分钟运行一次过期检查,即 SELECT * FROM good_records where record_status = 'NEW' and notification_sent = false (和 SELECT * FROM good_records where record_status = 'VALIDATED' and notification_sent = false ). 但是当我监视数据库资源的使用情况时,这两个查询的开销也就不足为奇了。
我的问题是,是否有可能以某种方式将索引放在表上,以便加快查询并节省数据库资源。
我已经简单地阅读了postgresql文档,但是没有很好的解决方案。

clj7thdc

clj7thdc1#

当然可以索引 enum 柱。但由于通常只有很少的不同值,部分索引通常更有效。细节取决于缺少的信息。
例如,假设只有几行 notification_sent = false ,您只需要检索 id ,此索引将服务于两个查询:

CREATE INDEX foo ON good_records (record_status, id)
WHERE notification_sent = false;

如果有很多写活动,请确保为表设置积极的自动真空设置,以防止表和索引膨胀,并允许仅索引扫描。
添加 id 只有当它能给你索引扫描时,索引才有意义。
如果你从不过滤 id ,使用 INCLUDE 改为子句(postgres 11或更高版本)。效率略高:

CREATE INDEX foo ON good_records (record_status) INCLUDE (id)
WHERE notification_sent = false;

相关:
优化postgres删除孤立记录
postgresql上的主动自动抽真空
postgres是否可以对具有联接表的查询使用仅索引扫描?

相关问题