Reputation: 790
I run into a rare situation when creating and deleting indexes on a table, let say that we create the following table:
create table my_table(id serial primary key, label text);
As this table contains a primary key we got our first index, in top of that lets add another one:
create index my_index on my_table(label);
And now some data...
insert into my_table (label) values ('alpha');
insert into my_table (label) values ('beta');
insert into my_table (label) values ('sigma');
insert into my_table (label) values ('sigma');
insert into my_table (label) values ('alpha');
insert into my_table (label) values ('gamma');
At this point we have two indexes working perfectly as we can see on the following sql explains
explain analyze select * from my_table where label = 'alpha';
Bitmap Heap Scan on my_table (cost=4.20..13.67 rows=6 width=36)
(actual time=0.022..0.022 rows=2 loops=1)
Recheck Cond: (label = 'alpha'::text)
Heap Blocks: exact=1
-> Bitmap Index Scan on my_index (cost=0.00..4.20 rows=6 width=0)
(actual time=0.016..0.016 rows=2 loops=1)
Index Cond: (label = 'alpha'::text)
Planning time: 0.084 ms
Execution time: 0.046 ms
The issue is that if I touch the indexes at this point either by adding a third one or recreating my_index I get painful sequential scans, for example:
drop index my_index;
create index my_index on my_table(label);
-- executing the same search againg
explain analyze select * from my_table where label = 'alpha';
Seq Scan on my_table (cost=0.00..1.08 rows=1 width=36)
(actual time=0.025..0.026 rows=2 loops=1)
Filter: (label = 'alpha'::text)
Rows Removed by Filter: 4
Planning time: 0.111 ms
Execution time: 0.036 ms
My understanding is that whenever I create an index the data on the table should be indexed -locking all write operations in the mean time- and that is not happening for some reason I ignore, does anyone know why this is ?
Thanks in advance,
Upvotes: 1
Views: 284
Reputation: 121574
You cannot draw any conclusions about the use of indexes in a table with several rows. Prepare test data with at least a few hundred thousand rows, e.g.:
drop table if exists my_table cascade;
create table my_table(id serial primary key, label text);
create index my_index on my_table(label);
insert into my_table (label)
select generate_series(1, 500000)::text
Update the table statistics before applying explain:
vacuum analyze my_table;
Run explain:
explain analyze select * from my_table where label = '123456';
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Index Scan using my_index on my_table (cost=0.42..8.44 rows=1 width=10) (actual time=0.288..0.290 rows=1 loops=1)
Index Cond: (label = '123456'::text)
Planning time: 80.753 ms
Execution time: 0.476 ms
(4 rows)
Upvotes: 1