是否可以对枚举建立索引?

问题描述 投票:0回答:1

问题实际上是关于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文档,但没有好的解决方案。

sql postgresql indexing postgresql-performance
1个回答
1
投票

当然可以索引enum列。但是,由于通常只有很少的不同值,因此partial indexes通常更有效。详细信息取决于缺少的信息。

例如,假设只有few行包含notification_sent = false,而您需要检索的全部是id,则此索引将同时服务于两个查询:

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

如果写活动很多,请确保具有积极的autovacuum设置for the table,以防止表和索引膨胀,并允许仅索引扫描。

id添加到索引只有在它可以给您index-only scans的情况下才有意义。

如果您从不过滤id,请改用INCLUDE子句(Postgres 11或更高版本)。效率略高:

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

相关:

© www.soinside.com 2019 - 2024. All rights reserved.