Friday, July 30, 2010

Indexing on function expression

Without index:

explain analyze 
select * 
from withdrawn_spent ws 
join account_category ac using(account_category_id) 
where md5(ac.account_category_full_description) = '845653b0977ca959df6a206b349f88be'

Nested Loop  (cost=9.34..847.37 rows=280 width=706) (actual time=0.655..4.406 rows=1298 loops=1)
  ->  Seq Scan on account_category ac  (cost=0.00..14.54 rows=2 width=214) (actual time=0.037..0.933 rows=1 loops=1)
        Filter: (md5((account_category_full_description)::text) = '845653b0977ca959df6a206b349f88be'::text)
  ->  Bitmap Heap Scan on withdrawn_spent ws  (cost=9.34..414.66 rows=140 width=531) (actual time=0.608..1.756 rows=1298 loops=1)
        Recheck Cond: ((ws.account_category_id)::text = (ac.account_category_id)::text)
        ->  Bitmap Index Scan on fki_withdrawn_spent__account_category_id  (cost=0.00..9.31 rows=140 width=0) (actual time=0.491..0.491 rows=1298 loops=1)
              Index Cond: ((ws.account_category_id)::text = (ac.account_category_id)::text)
Total runtime: 4.663 ms

Create Index:
create index ix_account_category__description on account_category (md5(account_category_full_description))

Execute this again:
explain analyze 
select * 
from withdrawn_spent ws 
join account_category ac using(account_category_id) 
where md5(ac.account_category_full_description) = '845653b0977ca959df6a206b349f88be'

Nested Loop  (cost=9.35..845.11 rows=280 width=706) (actual time=0.629..3.330 rows=1298 loops=1)
  ->  Index Scan using ix_account_category__description on account_category ac  (cost=0.00..12.29 rows=2 width=214) (actual time=0.013..0.016 rows=1 loops=1)
        Index Cond: (md5((account_category_full_description)::text) = '845653b0977ca959df6a206b349f88be'::text)
  ->  Bitmap Heap Scan on withdrawn_spent ws  (cost=9.34..414.66 rows=140 width=531) (actual time=0.605..1.636 rows=1298 loops=1)
        Recheck Cond: ((ws.account_category_id)::text = (ac.account_category_id)::text)
        ->  Bitmap Index Scan on fki_withdrawn_spent__account_category_id  (cost=0.00..9.31 rows=140 width=0) (actual time=0.488..0.488 rows=1298 loops=1)
              Index Cond: ((ws.account_category_id)::text = (ac.account_category_id)::text)
Total runtime: 3.585 ms

3.585 ms vs 4.663 ms

Index Scan vs Sequential Scan

Function-based index FTW! :-)

No comments:

Post a Comment