Fabian Büttner wrote:
> Hi,
>
> I have been thinking about a question on stackoverflow
> (http://stackoverflow.com/questions/19236363/select-distinct-faster-than-group-by),
> where some SQL framework removes duplicates from results using GROUP BY
> instead of DISTINCT.
> I don't want to discuss that this might not be a good idea. However, the
> core of that problem is the creation of temp b-trees when using ORDER BY
> ... DESC after GROUP BY.
> I wondered if the construction of a temp b-tree in the third query is
> intentional / by design?
I'd guess just "missing optimization opportunity". I think this fragment of code
is responsible for that optimization: src/select.c, sqlite3Select():
=== cut ===
/* If there is both a GROUP BY and an ORDER BY clause and they are
** identical, then disable the ORDER BY clause since the GROUP BY
** will cause elements to come out in the correct order. This is
** an optimization - the correct answer should result regardless.
** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER
** to disable this optimization for testing purposes.
*/
if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy, -1)==0
&& OptimizationEnabled(db, SQLITE_GroupByOrder) ){
pOrderBy = 0;
}
=== cut ===
Adding DESC to pOrderBy "breaks" sqlite3ExprListCompare(,) (note: just changing
sqlite3ExprListCompare to ignore it would be insufficient and will likely result
in *breakage*).
> I am using sqlite 3.8.1.
>
> sqlite> PRAGMA legacy_file_format=OFF;
>
> sqlite> create table test1 (x INTEGER);
> sqlite> create index test1_idx on test1(x);
> sqlite> explain query plan select x from test1 group by x order by x;
> selectid order from detail
> ---------- ---------- ----------
> -----------------------------------------------
> 0 0 0 SCAN TABLE test1 USING COVERING
> INDEX test1_idx
>
> create table test2 (x INTEGER);
> sqlite> create index test2_idx on test2(x);
> sqlite> explain query plan select x from test2 group by x order by x desc;
> selectid order from detail
> ---------- ---------- ----------
> -----------------------------------------------
> 0 0 0 SCAN TABLE test2 USING COVERING
> INDEX test2_idx
> 0 0 0 USE TEMP B-TREE FOR ORDER BY
>
> create table test3 (x INTEGER);
> sqlite> create index test3_idx on test3(x desc);
> sqlite> explain query plan select x from test3 group by x order by x desc;
> selectid order from detail
> ---------- ---------- ----------
> -----------------------------------------------
> 0 0 0 SCAN TABLE test3 USING COVERING
> INDEX test3_idx
> 0 0 0 USE TEMP B-TREE FOR ORDER BY
>
> To double check:
>
> sqlite> explain query plan select x from test3 order by x desc;
> selectid order from detail
> ---------- ---------- ----------
> -----------------------------------------------
> 0 0 0 SCAN TABLE test3 USING COVERING
> INDEX test3_idx
>
>
> Regards
> Fabian
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users