我有下表:
CREATE TABLE foo
(
c1 integer,
c2 text
)
创建如下:
CREATE INDEDX ON foo();
INSERT INTO foo
SELECT i, md5(random()::text)
FROM generate_series(1, 1000000) AS i;
ANALYZE baz;
现在,我尝试了查询:
EXPLAIN (ANALYZE, BUFFERS) SELECT MAX(c2) FROM foo;
并得到以下计划:
Result (cost=0.08..0.09 rows=1 width=0) (actual time=0.574..0.574 rows=1 loops=1)
Buffers: shared read=5
InitPlan 1 (returns $0)
-> Limit (cost=0.00..0.08 rows=1 width=33) (actual time=0.570..0.571 rows=1 loops=1)
Buffers: shared read=5
-> Index Only Scan Backward using foo_c2_idx on foo (cost=0.00..79676.27 rows=1000000 width=33) (actual time=0.569..0.569 rows=1 loops=1)
Index Cond: (c2 IS NOT NULL)
Heap Fetches: 1
Buffers: shared read=5
我真正感到困惑的是,结果成本只是0.08.. 0.09
。为什么呢?
我想找到max
,如果我们在列上有一个索引,我们必须执行Index Only Scan
并读取至少一个索引叶子。依次读取叶子,随机访问1次,费用为4.因此,成本应该超过4。
我在这里想念的是什么?
答案 0 :(得分:1)
索引扫描的成本由LIMIT按比例分配。分配逻辑不会尝试将页面访问整合到整数中,因为在分配完成时,它已经全部折叠为单个浮点数。