为啥索引扫描应该只检索两行?
Posted
技术标签:
【中文标题】为啥索引扫描应该只检索两行?【英文标题】:Why does an index scan retrieve two rows when there should only be one?为什么索引扫描应该只检索两行? 【发布时间】:2020-01-15 20:05:55 【问题描述】:在修补pgbench
和EXPLAIN
时,我发现了以下内容:
[root@fc26c91163dc /]# pgbench -i
100000 of 100000 tuples (100%) done (elapsed 0.21 s, remaining 0.00 s)
vacuuming...
creating primary keys...
done.
[root@fc26c91163dc /]# psql
psql (12.1)
Type "help" for help.
postgres=# insert into pgbench_branches values (generate_series(2,100000),1,'');
INSERT 0 99999
postgres=# vacuum full analyze;
VACUUM
postgres=# EXPLAIN ANALYZE SELECT * FROM pgbench_accounts a JOIN pgbench_branches b ON (a.bid=b.bid) WHERE a.aid < 100;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Merge Join (cost=15.01..16.64 rows=106 width=194) (actual time=0.114..0.323 rows=99 loops=1)
Merge Cond: (b.bid = a.bid)
-> Index Scan using pgbench_branches_pkey on pgbench_branches b (cost=0.29..4247.29 rows=100000 width=97) (actual time=0.013..0.016 rows=2 loops=1)
-> Sort (cost=14.71..14.98 rows=106 width=97) (actual time=0.091..0.098 rows=99 loops=1)
Sort Key: a.bid
Sort Method: quicksort Memory: 38kB
-> Index Scan using pgbench_accounts_pkey on pgbench_accounts a (cost=0.29..11.15 rows=106 width=97) (actual time=0.008..0.038 rows=99 loops=1)
Index Cond: (aid < 100)
Planning Time: 0.690 ms
Execution Time: 0.380 ms
(10 rows)
通知Index Scan using pgbench_branches_pkey...actual time=0.013..0.016 rows=2...
pgbench_accounts
中只有一个不同的 bid
值:
postgres=# select distinct bid from pgbench_accounts ;
bid
-----
1
(1 row)
bid
是pgbench_branches
中的主键:
postgres=# select * from pgbench_branches where bid = 1;
bid | bbalance | filler
-----+----------+--------
1 | 0 |
(1 row)
那么为什么Index Scan
产生rows=2
而不是rows=1
?
【问题讨论】:
【参考方案1】:它不知道 pgbench_branches 中存在的下一行的出价>1,直到它读取下一行并看到它的出价>1。它可能能够从主键约束中推断出它,但它并不是为此而编写的。
【讨论】:
谢谢!这完全有道理以上是关于为啥索引扫描应该只检索两行?的主要内容,如果未能解决你的问题,请参考以下文章