X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [200.46.204.2]) by svr1.postgresql.org (Postfix) with ESMTP id D48E2D1CA40 for ; Thu, 29 Apr 2004 08:36:01 -0300 (ADT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (neptune.hub.org [200.46.204.2]) (amavisd-new, port 10024) with ESMTP id 16243-05 for ; Thu, 29 Apr 2004 08:35:44 -0300 (ADT) Received: from fzkmail2.fzk.de (fzkmail2.fzk.de [141.52.27.52]) by svr1.postgresql.org (Postfix) with SMTP id 8676BD1B43A for ; Thu, 29 Apr 2004 08:35:39 -0300 (ADT) Received: FROM resy5.fzk.de BY fzkmail2.fzk.de ; Thu Apr 29 13:35:39 2004 +0200 Received: œby rodos.fzk.de with ESMTP (8.8.6 (PHNE_17135)/8.7.1) id NAA27994; Thu, 29 Apr 2004 13:35:39 +0200 (METDST) From: Christoph Haller Message-Id: <200404291135.NAA07447@rodos> Subject: Re: Multi ordered select and indexing To: antal.attila@ritek.hu (Antal Attila) Date: Thu, 29 Apr 2004 13:35:38 METDST Cc: pgsql-sql@postgresql.org In-Reply-To: <000001c42937$637db7a0$0b02010a@atesz>; from "Antal Attila" at Apr 26, 104 4:40 pm X-Mailer: Elm [revision: 212.4] X-Virus-Scanned: by amavisd-new at postgresql.org X-Amavis-Alert: BAD HEADER Non-encoded 8-bit data (char 9C hex) in message header 'Received' Received: \234by rodos.fzk.de... ^ X-Spam-Status: No, hits=0.0 tagged_above=0.0 required=5.0 tests= X-Spam-Level: X-Archive-Number: 200404/314 X-Sequence-Number: 17689 Have you thought of using a functional index on both columns? Regards, Christoph > > Hi! > What is the simplest solution for this query type: > > SELECT * FROM tablename ORDER BY col1 ASC, col2 DESC; > > In our experience, postgres cannot use a multi-colum index on (col1, > col2) in this situation. Is custom operator class the easiest solution, > which can solve the reverse indexing on col2? Our problem with this > solution, is that we have to replace "DESC" with "USING myoperator". Is > it possible, that postgres can recognize "myoperator" without replacing > "DESC"? > We made new operators on int4 type starting with letter "/": > > CREATE OPERATOR CLASS int4_reverse_order_ops > FOR TYPE int4 USING btree AS > OPERATOR 1 /< , > OPERATOR 2 /<= , > OPERATOR 3 /= , > OPERATOR 4 />= , > OPERATOR 5 /> , > FUNCTION 1 int4_reverse_order_cmp(int4, int4); > > Create an index: > CREATE INDEX idx_test ON tablename (col1, col2 > int4_reverse_order_ops); > > Postgres use this index in this query: > EXPLAIN SELECT * FROM tablename ORDER BY col1 ASC, col2 USING /< limit > 10; > QUERY PLAN > ------------------------------------------------------------------------ > ------------ > Limit (cost=0.00..0.52 rows=10 width=8) > -> Index Scan using idx_test on tablename (cost=0.00..52.00 > rows=1000 width=8) > > Another problem: we have to replace the operators in WHERE conditions, > if that contains condition on col2. > EXPLAIN SELECT * FROM tablename WHERE col1 < 10 and col2 < 10 ORDER BY > col1, col2 using /< limit 10; > QUERY PLAN > ------------------------------------------------------------------------ > ----------- > Limit (cost=0.00..4.14 rows=10 width=8) > -> Index Scan using idx_test on tablename (cost=0.00..46.33 > rows=112 width=8) > Index Cond: (col1 < 10) > Filter: (col2 < 10) > > You can see, it use filtering on col2, but in the next case it can > indexing on col2 condition: > EXPLAIN SELECT * FROM tablename WHERE col1 < 10 and col2 /< 10 ORDER BY > col1, col2 using /< limit 10; > QUERY PLAN > ------------------------------------------------------------------------ > ----------- > Limit (cost=0.00..3.82 rows=10 width=8) > -> Index Scan using idx_test on tablename (cost=0.00..42.78 > rows=112 width=8) > Index Cond: ((col1 < 10) AND (col2 /< 10)) > > Can we do this easier? If can, how? > > After that, we have an other unsolved problem, if the col2's type is > TEXT, and we try to use a LIKE operator on it. We coludn't replace the > LIKE with own operator, because postgres exchange the "LIKE" with an > expression which contains ">=" and "<". We made own like operator: > "/~~", but we cannot tell postgres to use our own "/>=" and '/<' > operators instead of "/~~". > CREATE OPERATOR /~~ ( > leftarg = text, rightarg = text, procedure = textlike, > commutator = /~~ , negator = !~~ , > restrict = scalarltsel, join = scalarltjoinsel > ); > > Thanks in advance. >