I found my mistake. My supposition is working only if value column in t1 table is unique. But if I replace the index by unique one then plan is the same.
On Mon, May 3, 2010 at 5:57 PM, Alexander Korotkov <aekorot...@gmail.com>wrote: > Well, no, because that plan wouldn't produce the specified ordering; >> or at least it would be a lucky coincidence if it did. It's only >> sorting on t1.value. >> > I just don't find why it is coincidence. I think that such plan will always > produce result ordered by two columns, because such nested index scan always > produce this result. > > Let's consider some simple example in order to illustrate how this plan > works. > > t1 > id | value > ---+------ > 1 | 0.1 > 2 | 0.3 > 3 | 0.2 > > t2 > id | id1 | value > ---+-----+------ > 1 | 2 | 0.2 > 2 | 1 | 0.9 > 3 | 2 | 0.6 > 4 | 1 | 0.7 > 5 | 1 | 0.4 > 6 | 3 | 0.2 > > 1) The outer index scan will find the row of t1 with least value using > test1_value_idx. It will be row (1, 0.1) > 2) The inner index scan will find all the rows in t2 where id1 = 1 using > test2_id1_value_idx. But index test2_id1_value_idx have second order by > value column and the index scan result will be ordered by value. That's why > inner index scan will find rows (5, 1, 0.4), (4, 1, 0.7) and (2, 1, 0.9). > And following query output will be produced: > > value1 | value2 > --------+------- > 0.1 | 0.4 > 0.1 | 0.7 > 0.1 | 0.9 > 3) The outer index scan will find the row of t1 with the second value using > test1_value_idx. It will be row (3, 0.2) > 4) The inner index scan will find all the rows in t2 where id1 = 3 using > test2_id1_value_idx. This row is (6, 3, 0.2). The following query output > will be produced: > > value1 | value2 > --------+------- > 0.2 | 0.2 > 5) The outer index scan will find the row of t1 with the third value using > test1_value_idx. It will be row (2, 0.3) > 6) The inner index scan will find all the rows in t2 where id1 = 2 using > test2_id1_value_idx. These rows are (1, 2, 0.2) and (3, 2, 0.6). The > following query output will be produced: > > value1 | value2 > --------+------- > 0.3 | 0.2 > 0.3 | 0.6 > > And the whole query result is: > value1 | value2 > --------+------- > 0.1 | 0.4 > 0.1 | 0.7 > 0.1 | 0.9 > 0.2 | 0.2 > 0.3 | 0.2 > 0.3 | 0.6 > > And this result is really ordered by t1.value, t2.value. > I can't find error in my reasoning :) > > The query without limit produce similar plan. > > EXPLAIN SELECT t1.value AS value1, t2.value AS value2 FROM test1 t1 JOIN > test2 t2 ON t2.id1 = t1.id ORDER BY t1.value > > Nested Loop (cost=0.00..62109.86 rows=995025 width=16) > -> Index Scan using test1_value_idx on test1 t1 (cost=0.00..19.19 > rows=200 width=12) > -> Index Scan using test2_id1_value_idx on test2 t2 (cost=0.00..248.27 > rows=4975 width=12) > Index Cond: (t2.id1 = t1.id) > > And I checked that the result is ordered by t1.value and t2.value. > > 2010/4/26 Tom Lane <t...@sss.pgh.pa.us> > >> =?KOI8-R?B?68/Sz9TLz9cg4czFy9PBzsTS?= <aekorot...@gmail.com> writes: >> >> > So PostgreSQL planner can produce the plan I need but it doesn't produce >> > this plan when I specify particular second ordering column. >> >> Well, no, because that plan wouldn't produce the specified ordering; >> or at least it would be a lucky coincidence if it did. It's only >> sorting on t1.value. >> >> > So is there any >> > way to make planner produce desired plan when particular second ordering >> > column is specified? >> >> Not when the ordering columns come from two different tables. (If they >> were in the same table then scanning a two-column index could produce >> the demanded sort order.) I don't see any way to satisfy this query >> without an explicit sort step, which means it has to look at the whole >> join output. >> >> If you're willing to make assumptions like "the required 10 rows will be >> within the first 100 t1.value rows" then you could nest an ORDER BY >> t1.value LIMIT 100 query inside something that did an ORDER BY with both >> columns. But this fails if you have too many duplicate t1.value values, >> and your test case suggests that you might have a lot of them. In any >> case it would stop being fast if you make the inner LIMIT very large. >> >> regards, tom lane >> > >