我有以下疑问
SELECT pri.*
FROM patientreceiptitem pri
JOIN patientfinancialtransaction_patientreceiptitem pp ON pri.id = pp.receiptitems_id
JOIN patientfinancialtransaction pft ON pp.patientfinancialtransaction_id = pft.id
WHERE pri.createtime >= '2020-03-01'
AND pri.createtime < '2020-04-01'
它运行时间为 1.79 秒,输出 111,793 行
但是,当我添加一个更严格的条件时,如下所示:
JOIN patientbillconcession pbc ON pbc.id = pft.concession_id
性能会急剧下降。输出 10,338 行数据现在需要 8.185 秒。如果我向表的 JOIN 子句添加条件,也会出现同样的性能下降pft
:
SELECT pri.*
FROM patientreceiptitem pri
JOIN patientfinancialtransaction_patientreceiptitem pp ON pri.id = pp.receiptitems_id
JOIN patientfinancialtransaction pft ON pp.patientfinancialtransaction_id = pft.id
AND pft.concession_id IS NOT NULL
WHERE pri.createtime >= '2020-03-01'
AND pri.createtime < '2020-04-01'
concession_id
已在pft
表中编入索引。
任何指点都将十分有帮助。
我在 Arch Linux 上运行 Postgres 12。我的客户端是 DBeaver 7.3.2。
更新 1:我发现将以下内容更改为 LEFT JOIN 可在 1.914 秒内完成查询:
LEFT JOIN patientbillconcession pbc ON pbc.id = pft.concession_id
但添加AND pft.concession_id IS NOT NULL
WHERE 子句后,性能再次降低至 7.938 秒
答案1
由于值无法连接,pft.concession_id IS NOT NULL
因此查询中的having无关紧要。它们将被自然排除,因为要求存在匹配的记录。NULL
JOIN patientbillconcession
patientfinancialtransation
最简单的方法是从...开始EXPLAIN
然后 PostgreSQL 可以告诉您为什么返回结果需要这么长时间:
EXPLAIN SELECT pri.* FROM patientreceiptitem pri ...