/ Check-in [6fac0b92]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Skip-ahead is now just an optimization. If it gets confused, it falls back to an incremental scan with redundancy elimination.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | skip-ahead-distinct
Files: files | file ages | folders
SHA1: 6fac0b9212ecfe5013bacd70a90fc6d40c5091bb
User & Date: drh 2016-04-15 16:27:18
Context
2016-04-15
22:03
Add the SQLITE_SkipAhead optimization setting check-in: 87703b76 user: drh tags: skip-ahead-distinct
16:27
Skip-ahead is now just an optimization. If it gets confused, it falls back to an incremental scan with redundancy elimination. check-in: 6fac0b92 user: drh tags: skip-ahead-distinct
16:17
Skip-ahead does not always work. So we still have to check for redundancy. check-in: db5a2364 user: drh tags: skip-ahead-distinct
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/where.c.

  4577   4577     sqlite3ExprCacheClear(pParse);
  4578   4578     for(i=pWInfo->nLevel-1; i>=0; i--){
  4579   4579       int addr;
  4580   4580       pLevel = &pWInfo->a[i];
  4581   4581       pLoop = pLevel->pWLoop;
  4582   4582       sqlite3VdbeResolveLabel(v, pLevel->addrCont);
  4583   4583       if( pLevel->op!=OP_Noop ){
         4584  +#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
         4585  +      int n = -1;
         4586  +      int j, k, op;
         4587  +      int r1 = pParse->nMem+1;
  4584   4588         if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
  4585   4589          && (pLoop->wsFlags & WHERE_INDEXED)!=0
  4586   4590         ){
  4587   4591           /* This is the Skip-ahead optimization.  When doing a DISTINCT query
  4588   4592           ** that has WHERE_DISTINCT_ORDERED, use OP_SkipGT/OP_SkipLT to skip
  4589   4593           ** over all duplicate entries, rather than visiting all duplicates
  4590   4594           ** using OP_Next/OP_Prev. */
  4591         -        int j, k, op;
  4592         -        int r1 = pParse->nMem+1;
  4593         -        int n = -1;
  4594   4595           ExprList *pX = pWInfo->pDistinctSet;
  4595   4596           Index *pIdx = pLoop->u.btree.pIndex;
  4596   4597           for(j=0; j<pX->nExpr; j++){
  4597   4598             Expr *pE = sqlite3ExprSkipCollate(pX->a[j].pExpr);
  4598   4599             if( pE->op==TK_COLUMN ){
  4599   4600               if( pE->iTable!=pLevel->iTabCur ) continue;
  4600   4601               k = 1+sqlite3ColumnOfIndex(pIdx, pE->iColumn);
................................................................................
  4605   4606                 if( pI && sqlite3ExprCompare(pE,pI,0)<2 ){
  4606   4607                   n = k+1;
  4607   4608                   break;
  4608   4609                 }
  4609   4610               }
  4610   4611             }
  4611   4612           }
  4612         -        if( n>0 ){
  4613         -          for(j=0; j<n; j++){
  4614         -            sqlite3VdbeAddOp3(v, OP_Column, pLevel->iIdxCur, j, r1+j);
  4615         -          }
  4616         -          pParse->nMem += n;
  4617         -          op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT;
  4618         -          k = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n);
  4619         -          VdbeCoverageIf(v, op==OP_SeekLT);
  4620         -          VdbeCoverageIf(v, op==OP_SeekGT);
  4621         -          sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
  4622         -          sqlite3VdbeJumpHere(v, k);
         4613  +      }
         4614  +      if( n>0 ){
         4615  +        for(j=0; j<n; j++){
         4616  +          sqlite3VdbeAddOp3(v, OP_Column, pLevel->iIdxCur, j, r1+j);
  4623   4617           }
  4624         -      }else{
         4618  +        pParse->nMem += n;
         4619  +        op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT;
         4620  +        k = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n);
         4621  +        VdbeCoverageIf(v, op==OP_SeekLT);
         4622  +        VdbeCoverageIf(v, op==OP_SeekGT);
         4623  +        sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
         4624  +        sqlite3VdbeJumpHere(v, k);
         4625  +      }else
         4626  +#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
         4627  +      {
  4625   4628           /* The common case: Advance to the next row */
  4626   4629           sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
  4627   4630           sqlite3VdbeChangeP5(v, pLevel->p5);
  4628   4631           VdbeCoverage(v);
  4629   4632           VdbeCoverageIf(v, pLevel->op==OP_Next);
  4630   4633           VdbeCoverageIf(v, pLevel->op==OP_Prev);
  4631   4634           VdbeCoverageIf(v, pLevel->op==OP_VNext);