Description
Environment: Centos 6-x64, Postgres Plus Advanced Server 9.3.
I have a table with 4 columns with data as below:
id code_id effective_date name
24 12 "2015-09-15 02:57:47.626751+00" "dtsc_12"
429 215 "2015-09-15 02:57:47.626751+00" "dtsc_215"
430 215 "2015-09-15 02:57:47.626751+00" "dtsc_215"
465 233 "2015-09-15 02:57:47.626751+00" "dtsc_233"
466 233 "2015-09-15 02:57:47.626751+00" "dtsc_233"
468 234 "2015-09-15 02:57:47.626751+00" "dtsc_234"
And I want to get all row with condition: group by code_id and max(effective_date) < current_timestamp. So, the result I want:
id code_id effective_date name
24 12 "2015-09-15 02:57:47.626751+00" "dtsc_12"
429 215 "2015-09-15 02:57:47.626751+00" "dtsc_215"
465 233 "2015-09-15 02:57:47.626751+00" "dtsc_233"
468 234 "2015-09-15 02:57:47.626751+00" "dtsc_234"
My coding
create table win_a (
id int not null primary key,
code_id int,
effective_date timestamp with time zone,
name text
);
insert into win_a
select a, a/2, now() + trunc(random() * 100) * '1 day'::interval, 'dtsc_' || (a/2)::int
from generate_series(1, 500) a
ORDER BY random() ;
create index win_a_indx on win_a using btree ( code_id, effective_date desc);
-- query 1
select a.*
from (
select id, code_id, effective_date, name
, rank() over (partition by code_id order by effective_date desc, id) as rank
from win_a
where effective_date < current_timestamp
) a
where rank = 1 ;
-- query 2 -- false if in the same code_id -> have more than two same effective_date value
select a.*
from win_a a
join (
select code_id, max(effective_date) as max_ef
from win_a
where effective_date < current_timestamp
group by code_id ) b
on a.code_id = b.code_id and a.effective_date = b.max_ef;
-- query 3 -- false if in the same code_id -> have more than two same effective_date value
select a.*
from win_a a
where (code_id, effective_date) in
(select code_id, max(effective_date) as max_ef
from win_a
where effective_date < current_timestamp
group by code_id );
Question
Can I use index with window function? (with query 1, I try an index but Postgres still uses a seq-scan instead of an index-scan)
How can I improve my coding?