Compare commits

...

2 Commits

Author SHA1 Message Date
drh 9b489d8f36 Use OP_SorterColumns in aggregate queries. Remove OPFLAG_CLEARCACHE.
FossilOrigin-Name: 134e65c07f88218a9f9f0b526695a7121df31e68
2014-10-13 12:30:17 +00:00
drh ad711a2fdd Add the OP_SorterColumns opcode - an experiment in using a special case
opcode to decode the Sorter output rather than the generic OP_Column.  This
might be faster.  And with further work, it could eventually eliminate the
need for OP_OpenPseudo.

FossilOrigin-Name: b9c695e8859bb9972a9890bf2ccf341c1282ab77
2014-10-13 01:23:51 +00:00
5 changed files with 70 additions and 43 deletions
+8 -8
View File
@@ -1,5 +1,5 @@
C Remove\sthe\sVdbeCursor.lastRowid\scache\sof\sthe\scurrent\srowid,\ssince\smaintaining\nthe\scorrect\scache\svalue\suses\smore\sCPU\scycles\sthan\sjust\srecomputing\sthe\srowid\non\sthe\soccasions\swhen\sit\sis\sactually\sneeded.\s\sReplace\sit\swith\sthe\nVdbeCursor.aOffset\sfield\swhich\sused\sto\sbe\scomputed\sfrom\sVdbeCursor.aType\nwhen\sneeded.\sSaves\s100\sbytes\sof\scode\sspace\sand\sruns\s0.2%\sfaster.
D 2014-10-12T22:37:22.384
C Use\sOP_SorterColumns\sin\saggregate\squeries.\s\sRemove\sOPFLAG_CLEARCACHE.
D 2014-10-13T12:30:17.749
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -227,12 +227,12 @@ F src/printf.c 6b79bbd063dcbadca4cf617a4cde255bcc13ea64
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c f11533162b57ed5ed37f549add34cbcdf51f6712
F src/select.c 506c2ff4118892858ccdf02d4c5f282371e6c374
F src/shell.c 18ee8bbe9502d8848072dc2eddd1ea09254ba494
F src/sqlite.h.in 4a5e5158c189d2bcd45c7c4607c2c0eb6d25c153
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
F src/sqliteInt.h c417a25e2369f705b651897a2f1cc8da0e6aa1c4
F src/sqliteInt.h f7812f74f2d0c6041ef6b91a99c5a45f775dd408
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 961d5926e5a8fda611d385ec22c226b8635cd1cb
F src/table.c 2e99ef7ef16187e17033d9398dc962ce22dab5cb
@@ -289,7 +289,7 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8
F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a
F src/vdbe.c 97c6c50e272ed531bc3af308d5f156cfca0ce4f4
F src/vdbe.c 124df37e5583c5057f144b35378afcebd2600ad5
F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327
F src/vdbeInt.h e1173bd72b282633c2ec8f3a2f78b5117229f268
F src/vdbeapi.c 37a6c6ae284a97bcace365f2f0a225680c0499d9
@@ -1204,7 +1204,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 869c30e45cc87063be423c650f16b99e8adb3df0
R d569318d3e6a6b025c49ffecae9bf7d4
P b9c695e8859bb9972a9890bf2ccf341c1282ab77
R eebfd0e526b75853928a9d4bc3401243
U drh
Z e6cf351e034f82bffef92232dfc65ffe
Z 514d9bf63dadaa081007370f2b345ba2
+1 -1
View File
@@ -1 +1 @@
91384a7d727ef0f285cd430e829ba9f3852db50e
134e65c07f88218a9f9f0b526695a7121df31e68
+10 -26
View File
@@ -1171,7 +1171,6 @@ static void generateSortTail(
int addrBreak = sqlite3VdbeMakeLabel(v); /* Jump here to exit loop */
int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */
int addr;
int addrOnce = 0;
int iTab;
ExprList *pOrderBy = pSort->pOrderBy;
int eDest = pDest->eDest;
@@ -1179,11 +1178,8 @@ static void generateSortTail(
int regRow;
int regRowid;
int nKey;
int iSortTab; /* Sorter cursor to read from */
int nSortData; /* Trailing values to read from sorter */
u8 p5; /* p5 parameter for 1st OP_Column */
int i;
int bSeq; /* True if sorter record includes seq. no. */
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
struct ExprList_item *aOutEx = p->pEList->a;
#endif
@@ -1206,29 +1202,18 @@ static void generateSortTail(
nKey = pOrderBy->nExpr - pSort->nOBSat;
if( pSort->sortFlags & SORTFLAG_UseSorter ){
int regSortOut = ++pParse->nMem;
iSortTab = pParse->nTab++;
if( pSort->labelBkOut ){
addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
}
sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
VdbeCoverage(v);
codeOffset(v, p->iOffset, addrContinue);
sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
p5 = OPFLAG_CLEARCACHE;
bSeq = 0;
sqlite3VdbeAddOp4Int(v, OP_SorterColumns, nKey, nSortData, regRow, regSortOut);
}else{
addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
codeOffset(v, p->iOffset, addrContinue);
iSortTab = iTab;
p5 = 0;
bSeq = 1;
}
for(i=0; i<nSortData; i++){
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
if( i==0 ) sqlite3VdbeChangeP5(v, p5);
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
for(i=0; i<nSortData; i++){
sqlite3VdbeAddOp3(v, OP_Column, iTab, nKey+i+1, regRow+i);
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
}
}
switch( eDest ){
case SRT_Table:
@@ -5157,12 +5142,11 @@ int sqlite3Select(
sqlite3ExprCacheClear(pParse);
if( groupBySort ){
sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut);
}
for(j=0; j<pGroupBy->nExpr; j++){
if( groupBySort ){
sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
}else{
j = pGroupBy->nExpr;
sqlite3VdbeAddOp4Int(v, OP_SorterColumns, 0, j, iBMem, sortOut);
sqlite3VdbeAddOp1(v, OP_NullRow, sortPTab);
}else{
for(j=0; j<pGroupBy->nExpr; j++){
sAggInfo.directMode = 1;
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
}
-1
View File
@@ -2666,7 +2666,6 @@ struct AuthContext {
#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
#define OPFLAG_APPEND 0x08 /* This is likely to be an append */
#define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
#define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
+51 -7
View File
@@ -2239,11 +2239,6 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
** if the P4 argument is a P4_MEM use the value of the P4 argument as
** the result.
**
** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor,
** then the cache of the cursor is reset prior to extracting the column.
** The first OP_Column against a pseudo-table after the value of the content
** register has changed should have this bit set.
**
** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when
** the result is guaranteed to only be used as the argument of a length()
** or typeof() function, respectively. The loading of large blobs can be
@@ -2288,7 +2283,7 @@ case OP_Column: {
/* If the cursor cache is stale, bring it up-to-date */
rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error;
if( pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){
if( pC->cacheStatus!=p->cacheCtr ){
if( pC->nullRow ){
if( pCrsr==0 ){
assert( pC->pseudoTableReg>0 );
@@ -4251,7 +4246,7 @@ case OP_SorterCompare: {
** Write into register P2 the current sorter data for sorter cursor P1.
*/
case OP_SorterData: {
VdbeCursor *pC;
VdbeCursor *pC; /* Sorting cursor defined by P1 */
pOut = &aMem[pOp->p2];
pC = p->apCsr[pOp->p1];
@@ -4261,6 +4256,55 @@ case OP_SorterData: {
break;
}
/* Opcode: SorterColumns P1 P2 P3 P4 *
** Synopsis: r[P3@P2]=decode(r[P4])
**
** The P4 register contains a record that has just come out of a sorter.
** Decode columns P1 through P1+P2-1 into registers P3..P3+P2-1.
**
** This opcode is much faster than multiple calls to Column since it
** does not need to deal with corrupt record detection or default values
** or any of the other complications associated with a record read
** from disk.
*/
case OP_SorterColumns: {
Mem *pDest; /* Register P3 output register */
Mem *pLast; /* Register P3+P2-1 */
u32 serial_type; /* Serial type of a column value */
u32 idx; /* Index into the record header */
u32 d; /* Index into the data of the record */
int nSkip; /* Number of initial columns to skip */
const u8 *aKey; /* Complete text of the record */
assert( pOp->p4type==P4_INT32 );
assert( pOp->p4.i>0 && pOp->p4.i<=(p->nMem - p->nCursor) );
assert( pOp->p3>pOp->p4.i || pOp->p3+pOp->p2<=pOp->p4.i );
assert( pOp->p1>=0 );
assert( pOp->p2>0 );
assert( aMem[pOp->p4.i].flags & MEM_Blob );
aKey = (const u8*)aMem[pOp->p4.i].z;
pDest = &aMem[pOp->p3];
pLast = &pDest[pOp->p2-1];
idx = getVarint32(aKey, d);
nSkip = pOp->p1;
while( nSkip-- ){
assert( d<=aMem[pOp->p4.i].n );
idx += getVarint32(&aKey[idx], serial_type);
d += sqlite3VdbeSerialTypeLen(serial_type);
}
do{
assert( d<=aMem[pOp->p4.i].n );
idx += getVarint32(&aKey[idx], serial_type);
if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest);
d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pDest);
pDest->enc = encoding;
Deephemeralize(pDest);
REGISTER_TRACE((int)(pDest-aMem), pDest);
pDest++;
}while( pDest<=pLast );
break;
}
/* Opcode: RowData P1 P2 * * *
** Synopsis: r[P2]=data
**