我发现对索引列执行的查询会导致顺序扫描:
mydatabase=> explain analyze SELECT account_id,num_tokens,tok_holdings FROM tokacct WHERE address='00000000000000000';
QUERY PLAN
--------------------------------------------------------------------------------------------------
Seq Scan on tokacct (cost=0.00..6.69 rows=1 width=27) (actual time=0.046..0.046 rows=0 loops=1)
Filter: (address = '00000000000000000'::text)
Rows Removed by Filter: 225
Planning time: 0.108 ms
Execution time: 0.075 ms
(5 rows)
mydatabase=>
但是\di
显示我有一个唯一索引:
mydatabase=> \di
List of relations
Schema | Name | Type | Owner | Table
--------+-------------------------+-------+--------+----------------
......
public | tokacct_address_key | index | mydb | tokacct
.....
我的表是这样定义的:
CREATE TABLE tokacct (
tx_id BIGINT NOT NULL,
account_id SERIAL PRIMARY KEY,
state_acct_id INT NOT NULL DEFAULT 0,
num_tokens INT DEFAULT 0,
ts_created INT DEFAULT 0,
block_created INT DEFAULT 0,
address TEXT NOT NULL UNIQUE
tok_holdings TEXT DEFAULT ''
);
如您所见,address
字段被声明为UNIQUE
。 \di
还确认存在索引。那么,为什么在表上使用顺序扫描呢?
Seq Scan on tokacct (cost=0.00..6.69 rows=1 width=27) (actual time=0.046..0.046 rows=0 loops=1)
答案 0 :(得分:5)
创建一页表格:
[0, 1, 1, 2, 3, 5, 8, 13]
序列扫描:
db=# create table small as select g, chr(g) from generate_series(1,200) g;
SELECT 200
db=# create index small_i on small(g);
CREATE INDEX
db=# analyze small;
ANALYZE
创建三页表:
db=# explain (analyze, verbose, buffers) select g from small where g = 200;
QUERY PLAN
------------------------------------------------------------------------------------------------------
Seq Scan on public.small (cost=0.00..3.50 rows=1 width=4) (actual time=0.044..0.045 rows=1 loops=1)
Output: g
Filter: (small.g = 200)
Rows Removed by Filter: 199
Buffers: shared hit=1
Planning time: 1.360 ms
Execution time: 0.066 ms
(7 rows)
现在该表需要三个页面和两个索引,因此索引更便宜...
我怎么知道页数?它在(详细的)执行计划中是这样说的。和桌子?
db=# drop table small;
DROP TABLE
db=# create table small as select g, chr(g) from generate_series(1,500) g;
SELECT 500
db=# create index small_i on small(g);
CREATE INDEX
db=# analyze small;
ANALYZE
db=# explain (analyze, verbose, buffers) select g from small where g = 200;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
Index Only Scan using small_i on public.small (cost=0.27..8.29 rows=1 width=4) (actual time=3.194..3.195 rows=1 loops=1)
Output: g
Index Cond: (small.g = 200)
Heap Fetches: 1
Buffers: shared hit=1 read=2
Planning time: 0.271 ms
Execution time: 3.747 ms
(7 rows)
此处 2 表示第二页(从零开始计数)。
或再次从详细计划中获取:
db=# select max(ctid) from small;
max
--------
(2,48)
(1 row)
在这里, hit = 3