/ Check-in [eb434228]
Login

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

Overview
Comment:Add a column to the sqlite_stat2 table that contains the number of entries with exactly the same key as the sample. We do not yet do anything with this extra value. Some tests in analyze2.test are failing.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | query-planner-tweaks
Files: files | file ages | folders
SHA1: eb434228277c4bbbb1ad153ed3e6e3eeffe799a4
User & Date: drh 2011-08-05 21:13:42
Original Comment: Add a column to the sqlite_stat2 table that contains the number of entries with exactly the same key as the sample. We do not yet do anything with this extra value. Some tests in analyze2.test are failing.
Context
2011-08-05
22:31
Bug fixes to the sample-count logic for STAT2. A few test cases added. check-in: e93c248c user: drh tags: query-planner-tweaks
21:13
Add a column to the sqlite_stat2 table that contains the number of entries with exactly the same key as the sample. We do not yet do anything with this extra value. Some tests in analyze2.test are failing. check-in: eb434228 user: drh tags: query-planner-tweaks
2011-08-03
22:06
Merge the winopen-retry-logic branch into trunk. The biggest change here is to test scripts, which should now use such as copy_file and delete_file from tester.tcl rather than the raw file commands of TCL. check-in: b90c28be user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/analyze.c.

    39     39   ){
    40     40     static const struct {
    41     41       const char *zName;
    42     42       const char *zCols;
    43     43     } aTable[] = {
    44     44       { "sqlite_stat1", "tbl,idx,stat" },
    45     45   #ifdef SQLITE_ENABLE_STAT2
    46         -    { "sqlite_stat2", "tbl,idx,sampleno,sample" },
           46  +    { "sqlite_stat2", "tbl,idx,sampleno,sample,cnt" },
    47     47   #endif
    48     48     };
    49     49   
    50     50     int aRoot[] = {0, 0};
    51     51     u8 aCreateTbl[] = {0, 0};
    52     52   
    53     53     int i;
................................................................................
    90     90     }
    91     91   
    92     92     /* Open the sqlite_stat[12] tables for writing. */
    93     93     for(i=0; i<ArraySize(aTable); i++){
    94     94       sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
    95     95       sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
    96     96       sqlite3VdbeChangeP5(v, aCreateTbl[i]);
           97  +    VdbeComment((v, "%s", aTable[i].zName));
    97     98     }
    98     99   }
    99    100   
   100    101   /*
   101    102   ** Generate code to do an analysis of all indices associated with
   102    103   ** a single table.
   103    104   */
................................................................................
   115    116     int i;                       /* Loop counter */
   116    117     int topOfLoop;               /* The top of the loop */
   117    118     int endOfLoop;               /* The end of the loop */
   118    119     int jZeroRows = -1;          /* Jump from here if number of rows is zero */
   119    120     int iDb;                     /* Index of database containing pTab */
   120    121     int regTabname = iMem++;     /* Register containing table name */
   121    122     int regIdxname = iMem++;     /* Register containing index name */
   122         -  int regSampleno = iMem++;    /* Register containing next sample number */
   123         -  int regCol = iMem++;         /* Content of a column analyzed table */
          123  +  int regSampleno = iMem++;    /* Sampleno (stat2) or stat (stat1) */
          124  +#ifdef SQLITE_ENABLE_STAT2
          125  +  int regSample = iMem++;      /* The next sample value */
          126  +  int regSampleCnt = iMem++;   /* Number of occurrances of regSample value */
          127  +  int shortJump = 0;           /* Instruction address */
          128  +  int addrStoreStat2 = 0;      /* Address of subroutine to wrote to stat2 */
          129  +  int regNext = iMem++;        /* Index of next sample to record */
          130  +  int regSampleIdx = iMem++;   /* Index of next sample */
          131  +  int regReady = iMem++;       /* True if ready to store a stat2 entry */
          132  +  int regGosub = iMem++;       /* Register holding subroutine return addr */
          133  +  int regSample2 = iMem++;     /* Number of samples to acquire times 2 */
          134  +  int regCount = iMem++;       /* Number of rows in the table */
          135  +  int regCount2 = iMem++;      /* regCount*2 */
          136  +#endif
          137  +  int regCol = iMem++;         /* Content of a column in analyzed table */
   124    138     int regRec = iMem++;         /* Register holding completed record */
   125    139     int regTemp = iMem++;        /* Temporary use register */
   126    140     int regRowid = iMem++;       /* Rowid for the inserted record */
          141  +  int once = 1;                /* One-time initialization */
   127    142   
   128         -#ifdef SQLITE_ENABLE_STAT2
   129         -  int addr = 0;                /* Instruction address */
   130         -  int regTemp2 = iMem++;       /* Temporary use register */
   131         -  int regSamplerecno = iMem++; /* Index of next sample to record */
   132         -  int regRecno = iMem++;       /* Current sample index */
   133         -  int regLast = iMem++;        /* Index of last sample to record */
   134         -  int regFirst = iMem++;       /* Index of first sample to record */
   135         -#endif
   136    143   
   137    144     v = sqlite3GetVdbe(pParse);
   138    145     if( v==0 || NEVER(pTab==0) ){
   139    146       return;
   140    147     }
   141    148     if( pTab->tnum==0 ){
   142    149       /* Do not gather statistics on views or virtual tables */
................................................................................
   161    168     sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
   162    169   
   163    170     iIdxCur = pParse->nTab++;
   164    171     sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
   165    172     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
   166    173       int nCol;
   167    174       KeyInfo *pKey;
          175  +    int addrIfNot;               /* address of OP_IfNot */
          176  +    int *aChngAddr;              /* Array of jump instruction addresses */
   168    177   
   169    178       if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
          179  +    VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
   170    180       nCol = pIdx->nColumn;
   171    181       pKey = sqlite3IndexKeyinfo(pParse, pIdx);
   172    182       if( iMem+1+(nCol*2)>pParse->nMem ){
   173    183         pParse->nMem = iMem+1+(nCol*2);
   174    184       }
          185  +    aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*pIdx->nColumn);
          186  +    if( aChngAddr==0 ) continue;
   175    187   
   176    188       /* Open a cursor to the index to be analyzed. */
   177    189       assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
   178    190       sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb,
   179    191           (char *)pKey, P4_KEYINFO_HANDOFF);
   180    192       VdbeComment((v, "%s", pIdx->zName));
   181    193   
................................................................................
   183    195       sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
   184    196   
   185    197   #ifdef SQLITE_ENABLE_STAT2
   186    198   
   187    199       /* If this iteration of the loop is generating code to analyze the
   188    200       ** first index in the pTab->pIndex list, then register regLast has
   189    201       ** not been populated. In this case populate it now.  */
   190         -    if( pTab->pIndex==pIdx ){
   191         -      sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regSamplerecno);
   192         -      sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2-1, regTemp);
   193         -      sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2, regTemp2);
   194         -
   195         -      sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regLast);
   196         -      sqlite3VdbeAddOp2(v, OP_Null, 0, regFirst);
   197         -      addr = sqlite3VdbeAddOp3(v, OP_Lt, regSamplerecno, 0, regLast);
   198         -      sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regLast, regFirst);
   199         -      sqlite3VdbeAddOp3(v, OP_Multiply, regLast, regTemp, regLast);
   200         -      sqlite3VdbeAddOp2(v, OP_AddImm, regLast, SQLITE_INDEX_SAMPLES*2-2);
   201         -      sqlite3VdbeAddOp3(v, OP_Divide,  regTemp2, regLast, regLast);
   202         -      sqlite3VdbeJumpHere(v, addr);
   203         -    }
   204         -
   205         -    /* Zero the regSampleno and regRecno registers. */
          202  +    if( once ){
          203  +      once = 0;
          204  +      sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2, regSample2);
          205  +
          206  +      sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount);
          207  +      sqlite3VdbeAddOp3(v, OP_Add, regCount, regCount, regCount2);
          208  +
          209  +
          210  +      /* Generate code for a subroutine that store the most recent sample
          211  +      ** in the sqlite_stat2 table
          212  +      */
          213  +      shortJump = sqlite3VdbeAddOp0(v, OP_Goto);
          214  +      sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 5, regRec, "aaaba", 0);
          215  +      VdbeComment((v, "begin stat2 write subroutine"));
          216  +      sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regRowid);
          217  +      sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regRowid);
          218  +      sqlite3VdbeAddOp2(v, OP_AddImm, regSampleno, 1);
          219  +      sqlite3VdbeAddOp2(v, OP_AddImm, regReady, -1);
          220  +      addrStoreStat2 = sqlite3VdbeAddOp2(v, OP_IfPos, regReady, shortJump+1);
          221  +      sqlite3VdbeAddOp1(v, OP_Return, regGosub);
          222  +      VdbeComment((v, "end stat2 write subroutine"));
          223  +      sqlite3VdbeJumpHere(v, shortJump);
          224  +    }
          225  +    /* Reset state registers */
          226  +    sqlite3VdbeAddOp2(v, OP_Copy, regCount2, regNext);
          227  +    shortJump = sqlite3VdbeAddOp3(v, OP_Lt, regSample2, 0, regCount);
          228  +    sqlite3VdbeAddOp3(v, OP_Divide, regSample2, regCount, regNext);
          229  +    sqlite3VdbeJumpHere(v, shortJump);
   206    230       sqlite3VdbeAddOp2(v, OP_Integer, 0, regSampleno);
   207         -    sqlite3VdbeAddOp2(v, OP_Integer, 0, regRecno);
   208         -    sqlite3VdbeAddOp2(v, OP_Copy, regFirst, regSamplerecno);
   209         -#endif
          231  +    sqlite3VdbeAddOp2(v, OP_Integer, 0, regSampleIdx);
          232  +    sqlite3VdbeAddOp2(v, OP_Integer, 0, regReady);
          233  +
          234  +#endif /* SQLITE_ENABLE_STAT2 */
   210    235   
   211    236       /* The block of memory cells initialized here is used as follows.
   212    237       **
   213    238       **    iMem:                
   214    239       **        The total number of rows in the table.
   215    240       **
   216    241       **    iMem+1 .. iMem+nCol: 
................................................................................
   232    257       }
   233    258   
   234    259       /* Start the analysis loop. This loop runs through all the entries in
   235    260       ** the index b-tree.  */
   236    261       endOfLoop = sqlite3VdbeMakeLabel(v);
   237    262       sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop);
   238    263       topOfLoop = sqlite3VdbeCurrentAddr(v);
   239         -    sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1);
          264  +    sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1);  /* Increment row counter */
   240    265   
   241    266       for(i=0; i<nCol; i++){
   242    267         CollSeq *pColl;
   243    268         sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol);
   244    269         if( i==0 ){
   245    270   #ifdef SQLITE_ENABLE_STAT2
   246    271           /* Check if the record that cursor iIdxCur points to contains a
   247    272           ** value that should be stored in the sqlite_stat2 table. If so,
   248    273           ** store it.  */
   249         -        int ne = sqlite3VdbeAddOp3(v, OP_Ne, regRecno, 0, regSamplerecno);
   250         -        assert( regTabname+1==regIdxname 
   251         -             && regTabname+2==regSampleno
   252         -             && regTabname+3==regCol
   253         -        );
   254         -        sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
   255         -        sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 4, regRec, "aaab", 0);
   256         -        sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regRowid);
   257         -        sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regRowid);
          274  +        int ne = sqlite3VdbeAddOp3(v, OP_Ne, iMem, 0, regNext);
          275  +        VdbeComment((v, "jump if not a sample"));
          276  +        sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrStoreStat2);
          277  +        sqlite3VdbeAddOp2(v, OP_Copy, regCol, regSample);
          278  +        sqlite3VdbeAddOp2(v, OP_AddImm, regReady, 1);
   258    279   
   259         -        /* Calculate new values for regSamplerecno and regSampleno.
          280  +        /* Calculate new values for regNextSample.  Where N is the number
          281  +        ** of rows in the table and S is the number of samples to take:
   260    282           **
   261         -        **   sampleno = sampleno + 1
   262         -        **   samplerecno = samplerecno+(remaining records)/(remaining samples)
          283  +        **   nextSample = (sampleNumber*N*2 + N)/(2*S)
   263    284           */
   264         -        sqlite3VdbeAddOp2(v, OP_AddImm, regSampleno, 1);
   265         -        sqlite3VdbeAddOp3(v, OP_Subtract, regRecno, regLast, regTemp);
   266         -        sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
   267         -        sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regTemp2);
   268         -        sqlite3VdbeAddOp3(v, OP_Subtract, regSampleno, regTemp2, regTemp2);
   269         -        sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regTemp, regTemp);
   270         -        sqlite3VdbeAddOp3(v, OP_Add, regSamplerecno, regTemp, regSamplerecno);
   271         -
          285  +        sqlite3VdbeAddOp2(v, OP_AddImm, regSampleIdx, 1);
          286  +        sqlite3VdbeAddOp3(v, OP_Multiply, regSampleIdx, regCount2, regNext);
          287  +        sqlite3VdbeAddOp3(v, OP_Add, regNext, regCount, regNext);
          288  +        sqlite3VdbeAddOp3(v, OP_Divide, regSample2, regNext, regNext);
   272    289           sqlite3VdbeJumpHere(v, ne);
   273         -        sqlite3VdbeAddOp2(v, OP_AddImm, regRecno, 1);
   274    290   #endif
   275    291   
   276    292           /* Always record the very first row */
   277         -        sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1);
          293  +        addrIfNot = sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1);
   278    294         }
   279    295         assert( pIdx->azColl!=0 );
   280    296         assert( pIdx->azColl[i]!=0 );
   281    297         pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
   282         -      sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1,
   283         -                       (char*)pColl, P4_COLLSEQ);
          298  +      aChngAddr[i] = sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1,
          299  +                                      (char*)pColl, P4_COLLSEQ);
   284    300         sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
   285         -    }
   286         -    if( db->mallocFailed ){
   287         -      /* If a malloc failure has occurred, then the result of the expression 
   288         -      ** passed as the second argument to the call to sqlite3VdbeJumpHere() 
   289         -      ** below may be negative. Which causes an assert() to fail (or an
   290         -      ** out-of-bounds write if SQLITE_DEBUG is not defined).  */
   291         -      return;
          301  +      VdbeComment((v, "jump if column %d changed", i));
          302  +#ifdef SQLITE_ENABLE_STAT2
          303  +      if( i==0 && addrStoreStat2 ){
          304  +        sqlite3VdbeAddOp2(v, OP_AddImm, regSampleCnt, 1);
          305  +        VdbeComment((v, "incr repeat count"));
          306  +      }
          307  +#endif
   292    308       }
   293    309       sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
   294    310       for(i=0; i<nCol; i++){
   295         -      int addr2 = sqlite3VdbeCurrentAddr(v) - (nCol*2);
          311  +      sqlite3VdbeJumpHere(v, aChngAddr[i]);  /* Set jump dest for the OP_Ne */
   296    312         if( i==0 ){
   297         -        sqlite3VdbeJumpHere(v, addr2-1);  /* Set jump dest for the OP_IfNot */
          313  +        sqlite3VdbeJumpHere(v, addrIfNot);   /* Jump dest for OP_IfNot */
          314  +#ifdef SQLITE_ENABLE_STAT2
          315  +        sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrStoreStat2);
          316  +        sqlite3VdbeAddOp2(v, OP_Integer, 1, regSampleCnt);
          317  +#endif        
   298    318         }
   299         -      sqlite3VdbeJumpHere(v, addr2);      /* Set jump dest for the OP_Ne */
   300    319         sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1);
   301    320         sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
   302    321       }
          322  +    sqlite3DbFree(db, aChngAddr);
   303    323   
   304    324       /* End of the analysis loop. */
   305    325       sqlite3VdbeResolveLabel(v, endOfLoop);
   306    326       sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
   307    327       sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
          328  +#ifdef SQLITE_ENABLE_STAT2
          329  +    sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrStoreStat2);
          330  +#endif        
   308    331   
   309    332       /* Store the results in sqlite_stat1.
   310    333       **
   311    334       ** The result is a single row of the sqlite_stat1 table.  The first
   312    335       ** two columns are the names of the table and index.  The third column
   313    336       ** is a string composed of a list of integer statistics about the
   314    337       ** index.  The first integer in the list is the total number of entries

Changes to src/vdbe.c.

  1049   1049   */
  1050   1050   case OP_Copy: {             /* in1, out2 */
  1051   1051     pIn1 = &aMem[pOp->p1];
  1052   1052     pOut = &aMem[pOp->p2];
  1053   1053     assert( pOut!=pIn1 );
  1054   1054     sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
  1055   1055     Deephemeralize(pOut);
  1056         -  REGISTER_TRACE(pOp->p2, pOut);
  1057   1056     break;
  1058   1057   }
  1059   1058   
  1060   1059   /* Opcode: SCopy P1 P2 * * *
  1061   1060   **
  1062   1061   ** Make a shallow copy of register P1 into register P2.
  1063   1062   **
................................................................................
  1536   1535   ** To force any register to be an integer, just add 0.
  1537   1536   */
  1538   1537   case OP_AddImm: {            /* in1 */
  1539   1538     pIn1 = &aMem[pOp->p1];
  1540   1539     memAboutToChange(p, pIn1);
  1541   1540     sqlite3VdbeMemIntegerify(pIn1);
  1542   1541     pIn1->u.i += pOp->p2;
         1542  +  REGISTER_TRACE(pOp->p1, pIn1);
  1543   1543     break;
  1544   1544   }
  1545   1545   
  1546   1546   /* Opcode: MustBeInt P1 P2 * * *
  1547   1547   ** 
  1548   1548   ** Force the value in register P1 to be an integer.  If the value
  1549   1549   ** in P1 is not an integer and cannot be converted into an integer

Changes to test/analyze2.test.

    67     67   do_test analyze2-1.1 {
    68     68     execsql { CREATE TABLE t1(x PRIMARY KEY) }
    69     69     for {set i 0} {$i < 1000} {incr i} {
    70     70       execsql { INSERT INTO t1 VALUES($i) }
    71     71     }
    72     72     execsql { 
    73     73       ANALYZE;
    74         -    SELECT * FROM sqlite_stat2;
           74  +    SELECT tbl, idx, sampleno, sample FROM sqlite_stat2;
    75     75     }
    76         -} [list t1 sqlite_autoindex_t1_1 0 50  \
           76  +} [list t1 sqlite_autoindex_t1_1 0 49  \
    77     77           t1 sqlite_autoindex_t1_1 1 149 \
    78     78           t1 sqlite_autoindex_t1_1 2 249 \
    79     79           t1 sqlite_autoindex_t1_1 3 349 \
    80     80           t1 sqlite_autoindex_t1_1 4 449 \
    81     81           t1 sqlite_autoindex_t1_1 5 549 \
    82     82           t1 sqlite_autoindex_t1_1 6 649 \
    83     83           t1 sqlite_autoindex_t1_1 7 749 \
    84     84           t1 sqlite_autoindex_t1_1 8 849 \
    85     85           t1 sqlite_autoindex_t1_1 9 949 \
    86     86   ]
    87     87   
    88     88   do_test analyze2-1.2 {
    89     89     execsql {
    90         -    DELETE FROM t1 WHERe x>9;
           90  +    DELETE FROM t1 WHERE x>9;
    91     91       ANALYZE;
    92     92       SELECT tbl, idx, group_concat(sample, ' ') FROM sqlite_stat2;
    93     93     }
    94     94   } {t1 sqlite_autoindex_t1_1 {0 1 2 3 4 5 6 7 8 9}}
    95     95   do_test analyze2-1.3 {
    96     96     execsql {
    97     97       DELETE FROM t1 WHERE x>8;
................................................................................
   185    185     execsql ANALYZE
   186    186     execsql { 
   187    187       SELECT tbl,idx,group_concat(sample,' ') 
   188    188       FROM sqlite_stat2 
   189    189       WHERE idx = 't1_x' 
   190    190       GROUP BY tbl,idx
   191    191     }
   192         -} {t1 t1_x {100 299 499 699 899 ajj cjj ejj gjj ijj}}
          192  +} {t1 t1_x {99 299 499 699 899 ajj cjj ejj gjj ijj}}
   193    193   do_test analyze2-3.2 {
   194    194     execsql { 
   195    195       SELECT tbl,idx,group_concat(sample,' ') 
   196    196       FROM sqlite_stat2 
   197    197       WHERE idx = 't1_y' 
   198    198       GROUP BY tbl,idx
   199    199     }
   200         -} {t1 t1_y {100 299 499 699 899 ajj cjj ejj gjj ijj}}
          200  +} {t1 t1_y {99 299 499 699 899 ajj cjj ejj gjj ijj}}
   201    201   
   202    202   do_eqp_test 3.3 {
   203    203     SELECT * FROM t1 WHERE x BETWEEN 100 AND 500 AND y BETWEEN 'a' AND 'b'
   204    204   } {
   205    205     0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~50 rows)}
   206    206   }
   207    207   do_eqp_test 3.4 {