有人遇到过这种情况吗?Postgres 企业数据库高级服务器 11.5.12
sysdate()
(Oracle 专有)在本例中会产生 4,782 行的 Seq Scan:
EXPLAIN SELECT p.id, p.practice
FROM PatientStatistics ps
INNER JOIN Patients p
ON p.id=ps.patient
WHERE ps.nextfutureapptdateservertime <= sysdate()
ORDER BY p.id ASC;
Hash Join (cost=799.81..1761.53 rows=4782 width=8)
Hash Cond: (p.id = ps.patient)
-> Index Only Scan using patients_index3 on patients p (cost=0.29..921.44 rows=15442 width=8)
-> Hash (cost=644.11..644.11 rows=4782 width=4)
-> Seq Scan on patientstatistics ps (cost=0.00..644.11 rows=4782 width=4)
Filter: (nextfutureapptdateservertime <= sysdate)
更改为now()
or current_timestamp
(SQL Standard) 可解决此问题。Postgres 正确使用索引:
EXPLAIN SELECT p.id, p.practice
FROM PatientStatistics ps
INNER JOIN Patients p
ON p.id=ps.patient
WHERE ps.nextfutureapptdateservertime <= now()
ORDER BY p.id ASC;
Nested Loop (cost=0.57..51.41 rows=17 width=8)
-> Index Only Scan using "patientstatisti_idx$$_0c9a0048" on patientstatistics ps (cost=0.29..8.53 rows=17 width=4)
Index Cond: (nextfutureapptdateservertime <= now())
-> Index Scan using patients_pk on patients p (cost=0.29..2.52 rows=1 width=8)
Index Cond: (id = ps.patient)
有趣的是注意到这些函数的输出不同:
SELECT now();
SELECT current_timestamp;
15-JAN-20 09:36:41.932741 -05:00
15-JAN-20 09:36:41.932930 -05:00
SELECT sysdate();
15-JAN-20 09:37:17
也许 Postgres 的日期索引使用具有小数部分的日期时间进行散列。计划者看到它通过了一个没有小数的日期,并且它知道索引的键不会准确排列,因此它退回到扫描以确保查询提供 100% 准确的结果。
经过 30 分钟的谷歌搜索后,我在网上找不到任何相关信息。