hin*_*awa 1 sql postgresql indexing postgresql-performance
问题实际上是关于 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,
);
Run Code Online (Sandbox Code Playgroud)
我想每 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 文档,但没有好的解决方案。
当然可以对enum列进行索引。但由于通常只有几个不同的值,部分索引通常更有效。细节取决于缺失的信息。
例如,假设只有几行带有notification_sent = false,而您需要检索的只是id,该索引将同时服务于两个查询:
CREATE INDEX foo ON good_records (record_status, id)
WHERE notification_sent = false;
Run Code Online (Sandbox Code Playgroud)
如果有大量写入活动,请确保对表进行积极的自动清理设置,以防止表和索引膨胀并允许仅索引扫描。
添加id到索引只有在它可以为您提供仅索引扫描时才有意义。
如果您从不过滤id,请改用该INCLUDE子句(Postgres 11 或更高版本)。稍微高效一点:
CREATE INDEX foo ON good_records (record_status) INCLUDE (id)
WHERE notification_sent = false;
Run Code Online (Sandbox Code Playgroud)
有关的:
| 归档时间: |
|
| 查看次数: |
1235 次 |
| 最近记录: |