YES! Thank you!
Many thanks for the ".eqp full" tip also, that really explains a lot
(though I don't really understand any of it yet).

Have a great day!
Gerlando


On Mon, Jan 28, 2019 at 6:50 AM Keith Medcalf <kmedc...@dessus.com> wrote:

>
> Do you perhaps want this:
>
> select source1,
>        source2,
>        (
>         select min(ts)
>           from rolling
>          where source1 = x.source1
>            and source2 = x.source2
>        )
>   from (
>         select distinct source1,
>                         source2
>           from rolling
>        ) as x;
>
> SQLite version 3.27.0 2019-01-28 00:42:06
> Enter ".help" for usage hints.
> Connected to a transient in-memory database.
> Use ".open FILENAME" to reopen on a persistent database.
> sqlite> .timer on
> sqlite> CREATE TABLE `rolling` (
>    ...>     `source1`    TEXT NOT NULL,
>    ...>     `source2`    TEXT NOT NULL,
>    ...>     `ts`    INTEGER NOT NULL,
>    ...>     `value`    TEXT
>    ...> );
> Run Time: real 0.002 user 0.000000 sys 0.000000
> sqlite>
> sqlite> CREATE INDEX `sources` ON `rolling` (
>    ...>     `source1`,
>    ...>     `source2`,
>    ...>     `ts`
>    ...> );
> Run Time: real 0.001 user 0.000000 sys 0.000000
> sqlite>
> sqlite> INSERT INTO rolling
>    ...>     WITH RECURSIVE
>    ...>       src1( source1 ) AS ( VALUES("aaa") UNION ALL VALUES("bbb") ),
>    ...>       src2( source2 ) AS ( VALUES("X1") UNION ALL VALUES("X2")
> UNION ALL
>    ...> VALUES("X3") UNION ALL VALUES("X4") ),
>    ...>       cnt( ts, value) AS (
>    ...>       VALUES( 0, "ZZZZ")
>    ...>         UNION ALL
>    ...>       SELECT ts+1, value FROM cnt LIMIT 1000000)
>    ...>
>    ...>     select src1.source1, src2.source2, cnt.* from src1, src2, cnt;
> Run Time: real 8.920 user 8.843750 sys 0.078125
> sqlite>
> sqlite> analyze;
> Run Time: real 1.285 user 1.281250 sys 0.000000
> sqlite> .eqp full
> sqlite>
> sqlite> select source1,
>    ...>        source2,
>    ...>        (
>    ...>         select min(ts)
>    ...>           from rolling
>    ...>          where source1 = x.source1
>    ...>            and source2 = x.source2
>    ...>        )
>    ...>   from (
>    ...>         select distinct source1,
>    ...>                         source2
>    ...>           from rolling
>    ...>        ) as x;
> QUERY PLAN
> |--CO-ROUTINE 2
> |  `--SCAN TABLE rolling USING COVERING INDEX sources (~7864320 rows)
> |--SCAN SUBQUERY 2 AS x (~7864320 rows)
> `--CORRELATED SCALAR SUBQUERY 1
>    `--SEARCH TABLE rolling USING COVERING INDEX sources (source1=? AND
> source2=?) (~983040 rows)
> addr  opcode         p1    p2    p3    p4             p5  comment
> ----  -------------  ----  ----  ----  -------------  --  -------------
> 0     Init           0     64    0                    00  Start at 64
> 1     InitCoroutine  1     23    2                    00  x
> 2     Null           1     4     0                    08  r[4]=NULL
> 3     OpenRead       4     3     0     k(4,,,,)       00  root=3 iDb=0;
> sources
> 4     ColumnsUsed    4     0     0     3              00
> 5     Explain        5     0     0     SCAN TABLE rolling USING COVERING
> INDEX sources (~7864320 rows)  00
> 6     Noop           0     0     0                    00  Begin
> WHERE-loop0: rolling
> 7     Rewind         4     21    2     0              00
> 8         Noop           0     0     0                    00  Begin
> WHERE-core
> 9         Column         4     0     2                    00
> r[2]=rolling.source1
> 10        Column         4     1     3                    00
> r[3]=rolling.source2
> 11        Ne             2     13    4     (BINARY)       80  if
> r[4]!=r[2] goto 13
> 12        Eq             3     20    5     (BINARY)       80  if
> r[5]==r[3] goto 20
> 13        Copy           2     4     1                    00
> r[4..5]=r[2..3]
> 14        Yield          1     0     0                    00
> 15        Noop           0     0     0                    00  End
> WHERE-core
> 16        Column         4     0     6                    00  r[6]=
> 17        Column         4     1     7                    00  r[7]=
> 18        SeekGT         4     21    6     2              00  key=r[6..7]
> 19      Goto           1     8     0                    00
> 20    Next           4     8     0                    01
> 21    Noop           0     0     0                    00  End WHERE-loop0:
> rolling
> 22    EndCoroutine   1     0     0                    00
> 23    Explain        23    0     0     SCAN SUBQUERY 2 AS x (~7864320
> rows)  00
> 24    Noop           0     0     0                    00  Begin
> WHERE-loop0: x
> 25    InitCoroutine  1     0     2                    00
> 26      Yield          1     62    0                    00  next row of x
> 27      Noop           0     0     0                    00  Begin
> WHERE-core
> 28      Copy           2     9     0                    00  r[9]=r[2];
> x.source1
> 29      Copy           3     10    0                    00  r[10]=r[3];
> x.source2
> 30      Null           0     12    12                   00
> r[12..12]=NULL; Init subquery result
> 31      Integer        1     13    0                    00  r[13]=1; LIMIT
> counter
> 32      Null           0     14    15                   00  r[14..15]=NULL
> 33      OpenRead       5     3     0     k(4,,,,)       00  root=3 iDb=0;
> sources
> 34      ColumnsUsed    5     0     0     7              00
> 35      Explain        35    0     0     SEARCH TABLE rolling USING
> COVERING INDEX sources (source1=? AND source2=?) (~983040 rows)  00
> 36      Noop           0     0     0                    00  Begin
> WHERE-loop0: rolling
> 37      Copy           2     16    0                    00  r[16]=r[2];
> x.source1
> 38      Copy           3     17    0                    00  r[17]=r[3];
> x.source2
> 39      CursorHint     5     0     0     AND(EQ(c0,r[16]),EQ(c1,r[17]))  00
> 40      Copy           2     18    0                    00  r[18]=r[2];
> x.source1
> 41      IsNull         18    54    0                    00  if r[18]==NULL
> goto 54
> 42      Copy           3     19    0                    00  r[19]=r[3];
> x.source2
> 43      IsNull         19    54    0                    00  if r[19]==NULL
> goto 54
> 44      Null           0     20    0                    00  r[20]=NULL
> 45      SeekGT         5     54    18    3              00  key=r[18..20]
> 46        IdxGT          5     54    18    2              00  key=r[18..19]
> 47        Noop           0     0     0                    00  Begin
> WHERE-core
> 48        Column         5     2     21                   00
> r[21]=rolling.ts
> 49        CollSeq        0     0     0     (BINARY)       00
> 50        AggStep        0     21    14    min(1)         01  accum=r[14]
> step(r[21])
> 51        Goto           0     55    0                    00  min() by
> index
> 52        Noop           0     0     0                    00  End
> WHERE-core
> 53      Next           5     46    0                    00
> 54      Noop           0     0     0                    00  End
> WHERE-loop0: rolling
> 55      AggFinal       14    1     0     min(1)         00  accum=r[14] N=1
> 56      Copy           14    12    0                    00  r[12]=r[14]
> 57      DecrJumpZero   13    58    0                    00  if
> (--r[13])==0 goto 58
> 58      Copy           12    11    0                    00  r[11]=r[12]
> 59      ResultRow      9     3     0                    00  output=r[9..11]
> 60      Noop           0     0     0                    00  End WHERE-core
> 61    Goto           0     26    0                    00
> 62    Noop           0     0     0                    00  End WHERE-loop0:
> x
> 63    Halt           0     0     0                    00
> 64    Transaction    0     0     3     0              01  usesStmtJournal=0
> 65    Goto           0     1     0                    00
> aaa|X1|0
> aaa|X2|0
> aaa|X3|0
> aaa|X4|0
> bbb|X1|0
> bbb|X2|0
> bbb|X3|0
> bbb|X4|0
> Run Time: real 0.134 user 0.000000 sys 0.000000
> sqlite>
>
> ---
> The fact that there's a Highway to Hell but only a Stairway to Heaven says
> a lot about anticipated traffic volume.
>
>
>
>
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to