sql> create table index_test (col1 integer, col2 integer default 0);
sql> do $$
begin
for i in 1..100000 loop
insert into index_test (col1) values(i);
end loop;
end;
$$;
sql> create index p_index_test2 on index_test (col1, col2);
sql> explain analyze select col2 from index_test where col1 > 40000;
+-----------------------------------------------------------------------------------------------------------------+
| QUERY PLAN |
|-----------------------------------------------------------------------------------------------------------------|
| Seq Scan on index_test (cost=0.00..1693.00 rows=59718 width=4) (actual time=2.916..426.669 rows=60000 loops=1) |
| Filter: (col1 > 40000) |
| Rows Removed by Filter: 40000 |
| Planning time: 0.104 ms |
| Execution time: 829.769 ms |
+-----------------------------------------------------------------------------------------------------------------+
sql> SET enable_seqscan = OFF;
sql> explain analyze select col2 from index_test where col1 > 40000;
+--------------------------------------------------------------------------------------------------------------------------------------------+
| QUERY PLAN |
|--------------------------------------------------------------------------------------------------------------------------------------------|
| Index Only Scan using p_index_test2 on index_test (cost=0.29..1705.36 rows=59718 width=4) (actual time=0.032..427.644 rows=60000 loops=1) |
| Index Cond: (col1 > 40000) |
| Heap Fetches: 0 |
| Planning time: 0.076 ms |
| Execution time: 839.303 ms |
+--------------------------------------------------------------------------------------------------------------------------------------------+
The above is comparing two query plan. one is using Index-Only-Scan
the other is using Seq-Scan
.
At the fist, I expected that query planner uses Index-Only-Scan
for sure.
However, the two plan show similar cost and actual time figure and it even shows Index-Only-Scan
is more expensive.
Why?
I know that in case of Index-Scan
, it needs additional action fetching data from data table so that the Index-Scan
's cost could be more expensive than Seq-Scan
but this is not in the case of Index-Only-Scan
.
One thing my assumpting is because the cardinality of result is hight(40001~100000). I think high cardinality could make planner do many random-access and its cost is higher than sequential-access.
However, I think planner will use sequential-access(not random-access) because WHERE
clause is range-condition and index is always ordered.
Edit
Postgresql 10.5
As I understand, If it simplifies, the two plan will work like the below.
with Index-Only-Scan
- move to 40001
- read data sequentially up to 100000
cast = (jump to 40001 in index table) + (read 60000 sequentially in index table)
with Seq-Scan
- read data sequentially up to 100000
cast = (read 100000 sequentially in data table)
If the two plan have similar coat, it means (jump to 40001 in index table)
's cost is expensive as (read 40000 sequentially in data table)
Is my understanding wrong?
@
address the OP. We can see from the cost estimates in the query plans that some overhead is accounted for.