Compare commits

...

1 Commits

Author SHA1 Message Date
drh c08520d70a Whenever two or more OP_Column opcodes on the same cursor occur in succession,
try to reordering them so that the one that extracts the right-most column is
first, so that it will warm up the row cache for all those that follow.  This
gives a small performance boost.

FossilOrigin-Name: 08e8f04d1241db8f190686404874461371ffbeaa
2015-10-16 03:34:38 +00:00
7 changed files with 77 additions and 32 deletions
+13 -10
View File
@@ -1,5 +1,5 @@
C Performance\soptimization\sfor\sthe\sOP_Column\sopcode.
D 2015-10-15T21:30:24.579
C Whenever\stwo\sor\smore\sOP_Column\sopcodes\son\sthe\ssame\scursor\soccur\sin\ssuccession,\ntry\sto\sreordering\sthem\sso\sthat\sthe\sone\sthat\sextracts\sthe\sright-most\scolumn\sis\nfirst,\sso\sthat\sit\swill\swarm\sup\sthe\srow\scache\sfor\sall\sthose\sthat\sfollow.\s\sThis\ngives\sa\ssmall\sperformance\sboost.
D 2015-10-16T03:34:38.572
F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 8e42cb55739cd8c12e1fd25401956e2019448f6a
@@ -280,7 +280,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c c3a9c4209439b806c44cf30daf466955727bf46c
F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
F src/btree.c 0b74bc28b2dc907cba03b5b4b3b81584273be699
F src/btree.c ea8c62f65e57e49bd6b0988cd681aca7246b51af
F src/btree.h 40189aefdc2b830d25c8b58fd7d56538481bfdd7
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
F src/build.c d6162335d690396dfc5c4bd59e8b2b0c14ba6285
@@ -343,7 +343,7 @@ F src/shell.c d25df04168d6ba5a4fa05bdbf859df667f9eb621
F src/sqlite.h.in 839c818e16ea68703d90d17bd2bb3607191debce
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924
F src/sqliteInt.h 1ad779ee62efee60494af0a75d8d45592f9f53c3
F src/sqliteInt.h 5332b07164eef1db4a60d2f1301fbb33de71c6d9
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c 286f6398a4d2cd1e8ff0771e3d30f8dddb4768ea
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
@@ -401,11 +401,11 @@ F src/update.c aa10336a2719bd1b9f89004f3d7ba6d566623a49
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c c33faa487c474d41a082979206896988448c9df9
F src/vdbe.c 32865d7eb6d9241879b1ef62f017abf33811bc2e
F src/vdbe.h 4bc88bd0e06f8046ee6ab7487c0015e85ad949ad
F src/vdbeInt.h 8b867eac234e28627ffcace3cd4b4b79bbec664b
F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca
F src/vdbeaux.c fd00b489ab3f44f2dca1e4344faf289b7bfcf649
F src/vdbeaux.c 170a0eef214941c76f79697640219045e529fcc0
F src/vdbeblob.c 565fabd302f5fca3bdf3d56cac330483616a39b6
F src/vdbemem.c 19b3036aa4d676e7103b0fb5efd6327da455f915
F src/vdbesort.c 8b23930a1289526f6d2a3a9f2e965bcc963e4a68
@@ -1352,7 +1352,7 @@ F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
F tool/mkautoconfamal.sh d1a2da0e15b2ed33d60af35c7e9d483f13a8eb9f
F tool/mkkeywordhash.c dfff09dbbfaf950e89af294f48f902181b144670
F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b
F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e
F tool/mkopcodeh.tcl 726340f306e455b478fbe777d71467d220fd3aa5
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl 84af2b180484323a2ea22a2279e8bd9e3e1e492e
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
@@ -1391,7 +1391,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 871e091df651b2275a672c35ff938bd4b6db0d7f
R 2a9ee0eee7d0527a150149dc10bab0fb
P 076be5474df628bbbfd2b645adba30e1e093acd0
R fa3f71993fa566414c3dbec59bd18acc
T *branch * reorder-column-opcodes
T *sym-reorder-column-opcodes *
T -sym-trunk *
U drh
Z 586c37c7b737d31273c8670597b9862e
Z 5fb19142d7f39beb17e045600e97d9ef
+1 -1
View File
@@ -1 +1 @@
076be5474df628bbbfd2b645adba30e1e093acd0
08e8f04d1241db8f190686404874461371ffbeaa
+3 -1
View File
@@ -4499,7 +4499,9 @@ static int accessPayload(
/* If required, populate the overflow page-list cache. */
if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){
assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage);
assert( pCur->aOverflow[iIdx]==0
|| pCur->aOverflow[iIdx]==nextPage
|| CORRUPT_DB );
pCur->aOverflow[iIdx] = nextPage;
}
+1
View File
@@ -1310,6 +1310,7 @@ struct sqlite3 {
#define SQLITE_Transitive 0x0200 /* Transitive constraints */
#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */
#define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */
#define SQLITE_RowCache 0x1000 /* Reorder OP_Column opcodes */
#define SQLITE_AllOpts 0xffff /* All optimizations */
/*
+1 -1
View File
@@ -656,7 +656,7 @@ int sqlite3VdbeExec(
/* Sanity checking on other operands */
#ifdef SQLITE_DEBUG
assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
assert( (pOp->opflags&~OPFLG_JMPDEST)==sqlite3OpcodeProperty[pOp->opcode] );
if( (pOp->opflags & OPFLG_IN1)!=0 ){
assert( pOp->p1>0 );
assert( pOp->p1<=(p->nMem-p->nCursor) );
+50 -13
View File
@@ -518,21 +518,67 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
**
** (5) Reclaim the memory allocated for storing labels.
**
** (6) Set the Op.opflags field on all opcodes, and especially the
** OPFLG_JMPDEST bit.
**
** (7) Reorders OP_Column opcodes against the same cursor so that the
** last column is extracted first. This is a performance optimization.
*/
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
int i;
int i, m;
int nMaxArgs = *pMaxFuncArgs;
Op *pOp;
Parse *pParse = p->pParse;
int *aLabel = pParse->aLabel;
p->readOnly = 1;
p->bIsReader = 0;
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
u8 opcode = pOp->opcode;
/* First cut at the Op.opcode flags */
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
pOp->opflags = sqlite3OpcodeProperty[pOp->opcode];
}
/* Resolve goto labels. And add OPFLG_JMPDEST flags to the
** destinations of jumps. */
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
if( (pOp->opflags & OPFLG_JUMP)!=0 ){
if( pOp->p2<0 ){
assert( -1-pOp->p2<pParse->nLabel );
pOp->p2 = aLabel[-1-pOp->p2];
}
if( pOp->p2>0 && pOp->p2<p->nOp ){
p->aOp[pOp->p2].opflags |= OPFLG_JMPDEST;
}
}
}
sqlite3DbFree(p->db, pParse->aLabel);
pParse->aLabel = 0;
pParse->nLabel = 0;
/* Third pass: fix up opcodes */
for(pOp=p->aOp, i=m=0; i<p->nOp; i++, pOp++){
/* NOTE: Be sure to update mkopcodeh.awk when adding or removing
** cases from this switch! */
switch( opcode ){
switch( pOp->opcode ){
case OP_Column: {
if( OptimizationEnabled(p->db, SQLITE_RowCache) && i>=m ){
/* Reorder OP_Column opcodes so that the right-most column is
** extracted first. This warms up the row cache and helps the
** subsequent OP_Column opcodes to run faster */
int j;
int b = 0;
int p2 = pOp->p2;
for(j=1; pOp[j].opcode==OP_Column; j++){
if( pOp[j].p1!=pOp->p1 ) break;
if( pOp[j].opflags & OPFLG_JMPDEST ) break;
if( pOp[j].p2>p2 ){ b = j; p2 = pOp[j].p2; }
}
if( b ) SWAP(Op, pOp[0], pOp[b]);
m = i+j;
}
break;
}
case OP_Transaction: {
if( pOp->p2!=0 ) p->readOnly = 0;
/* fall thru */
@@ -579,16 +625,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
break;
}
}
pOp->opflags = sqlite3OpcodeProperty[opcode];
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
assert( -1-pOp->p2<pParse->nLabel );
pOp->p2 = aLabel[-1-pOp->p2];
}
}
sqlite3DbFree(p->db, pParse->aLabel);
pParse->aLabel = 0;
pParse->nLabel = 0;
*pMaxFuncArgs = nMaxArgs;
assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) );
}
+8 -6
View File
@@ -126,6 +126,7 @@ incr nOp
# The following are the opcodes that are processed by resolveP2Values()
#
set rp2v_ops {
OP_Column
OP_Transaction
OP_AutoCommit
OP_Savepoint
@@ -211,12 +212,13 @@ puts "/* Properties such as \"out2\" or \"jump\" that are specified in"
puts "** comments following the \"case\" for each opcode in the vdbe.c"
puts "** are encoded into bitvectors as follows:"
puts "*/"
puts "#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */"
puts "#define OPFLG_IN1 0x0002 /* in1: P1 is an input */"
puts "#define OPFLG_IN2 0x0004 /* in2: P2 is an input */"
puts "#define OPFLG_IN3 0x0008 /* in3: P3 is an input */"
puts "#define OPFLG_OUT2 0x0010 /* out2: P2 is an output */"
puts "#define OPFLG_OUT3 0x0020 /* out3: P3 is an output */"
puts "#define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */"
puts "#define OPFLG_IN1 0x02 /* in1: P1 is an input */"
puts "#define OPFLG_IN2 0x04 /* in2: P2 is an input */"
puts "#define OPFLG_IN3 0x08 /* in3: P3 is an input */"
puts "#define OPFLG_OUT2 0x10 /* out2: P2 is an output */"
puts "#define OPFLG_OUT3 0x20 /* out3: P3 is an output */"
puts "#define OPFLG_JMPDEST 0x40 /* A jump destination */"
puts "#define OPFLG_INITIALIZER \173\\"
for {set i 0} {$i<=$max} {incr i} {
if {$i%8==0} {