查询A执行以微秒:为什么添加一个窗口函数使得这个查询很慢?
SELECT t1.id
FROM (SELECT t0.id AS id FROM t0) AS t1
WHERE NOT (EXISTS (SELECT 1
FROM t2
WHERE t2.ph_id = t1.id AND t2.me_id = 1 AND t2.rt_id = 4))
LIMIT 20 OFFSET 0
但查询乙大约需要25秒时:
SELECT t1.id, count(*) OVER() AS count
FROM (SELECT t0.id AS id FROM t0) AS t1
WHERE NOT (EXISTS (SELECT 1
FROM t2
WHERE t2.ph_id = t1.id AND t2.me_id = 1 AND t2.rt_id = 4))
LIMIT 20 OFFSET 0
(所不同的是在选择子句中只有一个项目 - 一个窗口集合)
EXPLAIN输出如下,对于A:
Limit (cost=0.00..1.20 rows=20 width=4)
-> Nested Loop Anti Join (cost=0.00..3449.22 rows=57287 width=4)
Join Filter: (t2.ph_id = t0.id)
-> Seq Scan on t0 (cost=0.00..1323.88 rows=57288 width=4)
-> Materialize (cost=0.00..1266.02 rows=1 width=4)
-> Seq Scan on t2 (cost=0.00..1266.01 rows=1 width=4)
Filter: ((me_id = 1) AND (rt_id = 4))
而对于B:
Limit (cost=0.00..1.45 rows=20 width=4)
-> WindowAgg (cost=0.00..4165.31 rows=57287 width=4)
-> Nested Loop Anti Join (cost=0.00..3449.22 rows=57287 width=4)
Join Filter: (t2.ph_id = t0.id)
-> Seq Scan on t0 (cost=0.00..1323.88 rows=57288 width=4)
-> Materialize (cost=0.00..1266.02 rows=1 width=4)
-> Seq Scan on t2 (cost=0.00..1266.01 rows=1 width=4)
Filter: ((me_id = 1) AND (rt_id = 4))
我加入窗口集合限制之前得到排的总数,为建设一个分页UI的目的。