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
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to