Re: Index usage in order by with multiple columns in order-by-clause - Mailing list pgsql-sql
From | Andreas Joseph Krogh |
---|---|
Subject | Re: Index usage in order by with multiple columns in order-by-clause |
Date | |
Msg-id | 200708112145.14339.andreak@officenet.no Whole thread Raw |
In response to | Re: Index usage in order by with multiple columns in order-by-clause (hubert depesz lubaczewski <depesz@depesz.com>) |
List | pgsql-sql |
On Saturday 11 August 2007 21:05:22 hubert depesz lubaczewski wrote: > On Fri, Aug 10, 2007 at 04:53:12PM +0200, Andreas Joseph Krogh wrote: > > I have the following test-case: > > > > CREATE TABLE test( > > name varchar PRIMARY KEY, > > value varchar NOT NULL, > > created timestamp not null > > ); > > > > create index test_lowernamevalue_idx ON test ((lower(name) || > > lower(value))); create index test_lowernamevaluecreated_idx ON test > > ((lower(name) || lower(value)), created); > > andreak=# EXPLAIN ANALYZE select * from test order by lower(name) || > > lower(value) ASC, created DESC; > > QUERY PLAN > > ------------------------------------------------------------------------- > >------------------------------- Sort (cost=60.39..62.32 rows=770 > > width=72) (actual time=0.034..0.034 rows=0 loops=1) > > Sort Key: (lower((name)::text) || lower((value)::text)), created > > -> Seq Scan on test (cost=0.00..23.47 rows=770 width=72) (actual > > time=0.004..0.004 rows=0 loops=1) > > Total runtime: 0.123 ms > > (4 rows) > > In my application I often have a need to sort by more than 3 columns, so > > I'm really wondering if there is a way to make sorting of multiple > > columsn (each which may have different sort-order) use an index? > > Preferrably without having to create 2^N indexes. > > first of all - you can try with separate indexes on lower()||lower(), > and created. > > then - you can use a trick. > create a function that will reverse order of your date (using a simple > "-" operator) > and then index your lower() and output of this function. > > you will need to modify the query, but it's perfectly doable. > > for example: > create function test_ts(timestamp) returns interval as $BODY$ > begin > return '2000-01-01 00:00:00'::timestamp-$1; > end; > $BODY$ language plpgsql immutable; > > of course this particular date is irrelevant, we just have to substract > from something. > > then: > create index test_lowernamevaluecreated_idx2 ON test ((lower(name) || > lower(value)), test_ts(created)); > > and change your query to: > select * from test order by lower(name) || lower(value) ASC, > test_ts(created); it would show you what you need. > > depesz Thanks. I actaully do have an index on lower(a) || lower(b). Then, as Tom Lane explained, I need to have lots of indexes if I want to sort with different ordering (ASC|DESC) on each column. -- Andreas Joseph Krogh <andreak@officenet.no> Senior Software Developer / Manager ------------------------+---------------------------------------------+ OfficeNet AS | The most difficult thing in the world is to | Karenslyst Allé 11 | know how to do a thing and to watch | PO. Box 529 Skøyen | somebody else doing it wrong, without | 0214 Oslo | comment. | NORWAY | | Tlf: +47 24 15 38 90 | | Fax: +47 24 15 38 91 | | Mobile: +47 909 56 963 | | ------------------------+---------------------------------------------+