我有一个非常慢的查询,运行超过 30 秒:
SELECT DISTINCT id10
FROM
(SELECT j.id AS id10,
j.modified,
j.n_type AS n_type5
FROM note j
WHERE j.modified_date >= '2016-10-01 23:12:34.000000'
AND j.clientid = 16049
AND j.n_type IN ('n',
'n_1',
'n_custom',
'n_standard',
'n_status')
ORDER BY j.id ASC) t2
ORDER BY id10 ASC LIMIT 20;
解释分析:https ://explain.depesz.com/s/DU4
有什么办法可以改进这个查询吗?
modified_date
在和n_type
列上创建了一个新索引:
CREATE INDEX ix_n_type_modified
ON notes (n_type, timezone('Etc/UTC'::text, modified_date))
WHERE n_type IN ('n_1','n_custom','n_standard','n_status');
新解释分析:https ://explain.depesz.com/s/RsTr
查询仍需 >5 秒。
使用 Evan Carroll 提供的新查询进行新解释分析:https ://explain.depesz.com/s/yP4S
询问:
SELECT id AS id10
FROM
FROM note j
WHERE j.modified_date >= '2015-12-07 23:12:34.000000'
AND j.clientid = 16049
AND j.n_type IN ('n',
'n_1',
'n_custom',
'n_standard',
'n_status')
ORDER BY id10 ASC
LIMIT 20;
查询现在花费的时间更长。
note
是一种观点。它join
在工作表上有一个 ( note.jobid
-> jobs.id
)
我不能join
在这些表之间做任何其他事情,因为它们之间没有“链接”列。
\d+ note;
:
表“public.note” 栏目 | 类型 | 修饰符 | 存储 | 统计目标 | 描述 --------------+----------------------------+----- ---------------------------------------------- -----+------------+------------+---------------- ---------------------------------------------- ---------------------------------------------- ---------------------------------- 编号 | 二进制 | 不为空默认“nextval”('“note_id_seq”'::“regclass”)| 普通 | | 首要的关键 工作编号 | 二进制 | 非空默认 0 | 普通 | 说明 | “文本” | 默认 ''::"文本" | 扩展 | 修改日期 | 带时区的时间戳 | 默认“statement_timestamp”()| 普通 | | 修改日期 n_type | “n_type” | | 普通 | 指标: “note_pkey”主键,“btree”(“id”) "ix_note_gsdi_pk" "btree" (("id"::"text")) “ix_job_fk” “btree”(“jobid”) “ix_job_n_type” “btree”(“n_type”) "ix_note_jobid_type" "btree" ("jobid", "n_type") "ix_note_jobid_type_2" "btree" ("jobid", "n_type", "timezone"('Etc/UTC'::"text", "modified_date"))
查看note
架构note_user
- 此视图schema
与表不同note
:
SELECT r_30.id, r_30.jobid,
r_30.description,
timezone('Etc/UTC'::text, r_30.modified_date),
cj.clientid
FROM public.note r_30
JOIN public.jobs cj ON cj.id = r_30.jobid
;
表note
:
CREATE TABLE public.note
(
id bigint NOT NULL DEFAULT nextval('note_id_seq'::regclass), -- Primary key
jobid bigint NOT NULL DEFAULT 0,
description text DEFAULT ''::text,
n_type n_type,
modified_date timestamp with time zone DEFAULT statement_timestamp(),
CONSTRAINT note_pkey PRIMARY KEY (id)
);
表jobs
:
CREATE TABLE public.jobs
(
id bigint NOT NULL DEFAULT nextval('jobs_id_seq'::regclass),
clientid bigint NOT NULL DEFAULT 0,
description text NOT NULL DEFAULT ''::text,
modified_date timestamp without time zone DEFAULT statement_timestamp(),
CONSTRAINT jobs_pkey PRIMARY KEY (id)
);
自定义n_type
数据类型:
live_database=> \dT+ n_type
List of data types
Schema | Name | Internal name | Size | Elements | Access privileges | Description
--------+-----------------+-----------------+------+---------------------+-------------------+------------------------------
public | n_type | n_type | 4 | n_1 +| |
| | | | n_custom +| |
| | | | n_standard +| |
| | | | n_status +| |
(1 row)
取而代之的是,删除虚拟表并尝试直接查询。
您有多个索引选项,这在很大程度上取决于每个
WHERE
条件的选择性。您提到尝试在 上添加索引n_type
,但如果这与大多数(或大部分)记录相匹配,那么它不太可能改善情况。如果您有大量客户,那么您可以尝试使用索引clientid
代替,或者尝试组合使用(clientid, modified_date)
- 请记住,范围项必须排在最后才能在这里发挥作用。