From: drh Date: Wed, 28 Mar 2007 18:04:10 +0000 (+0000) Subject: Improvements to the XFER Optimization of the INSERT statement. (CVS 3736) X-Git-Tag: version-3.6.10~2434 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=95bad4c751899b0a18261ae65669ec42e1fbba5b;p=thirdparty%2Fsqlite.git Improvements to the XFER Optimization of the INSERT statement. (CVS 3736) FossilOrigin-Name: 53fff7d1f2f829010a2641c7738538b3155da4b2 --- diff --git a/manifest b/manifest index a7fdd54c5c..62f63e16b2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correctly\shandle\sNULLs\sin\sIN\soperators.\s\sTicket\s#2273.\nThe\schanges\sin\swhere.c\sand\sin\sthe\sWhereLevel.aInLoop\sstructure\sare\nnot\sstrictly\snecessary\sto\sfix\sthis\sproblem\s-\sthey\sjust\smake\sthe\scode\neasier\sto\sread.\s\sOnly\sthe\schange\sin\sOP_Next/OP_Prev\soperator\sof\svdbe.c\nis\srequired.\s(CVS\s3735) -D 2007-03-28T14:30:07 +C Improvements\sto\sthe\sXFER\sOptimization\sof\sthe\sINSERT\sstatement.\s(CVS\s3736) +D 2007-03-28T18:04:10 F Makefile.in 1fe3d0b46e40fd684e1e61f8e8056cefed16de9f F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -70,7 +70,7 @@ F src/expr.c a8740c24af3f39f2d502be1a1c640c96435eaac0 F src/func.c 94372fe3cf26b81d4dcdc15f98ff240c37c8c708 F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564 -F src/insert.c 9dbb62ba053769de20cf6b4ac73ceeb81ffc24f3 +F src/insert.c 4233b6444cb154ad3d75d5a3ff0a42ae4eabad8a F src/legacy.c 2631df6a861f830d6b1c0fe92b9fdd745b2c0cd6 F src/loadext.c c186ad5c9e8a0aaa73d0caf5f604d112e45e8b89 F src/main.c ed005bbc1d94670c8d9e2b93d446bd493119c44c @@ -302,7 +302,7 @@ F test/shared3.test 01e3e124dbb3859788aabc7cfb82f7ea04421749 F test/shared_err.test 841f7341eb07ed97c713bf89960a4e9199717193 F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5 F test/speed1.test 0ab227eae013d064f2205adcb9ee6f3c325b5bf4 -F test/speed2.test 31296ea46516ad6093e39f8622a4cbcc766923ec +F test/speed2.test 69f21e87b94fbabc4c78f8a62972923b17a0e9d0 F test/subquery.test ae324ee928c5fb463a3ce08a8860d6e7f1ca5797 F test/subselect.test 2d13fb7f450db3595adcdd24079a0dd1d2d6abc2 F test/sync.test d05397b8f89f423dd6dba528692019ab036bc1c3 @@ -442,7 +442,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 1c2656fdf6176a7365db4e11f4bbf47721da72b4 -R ad4f14fb479cf3da73d29eb9f4dc5165 +P 26348556d824c032851e409ac510cddb55c200bf +R db52877417d9d83d0ac7a145c2f8f5c7 U drh -Z 203008a1e44e27fee31001b2c9831dfe +Z 0cd9afba5878d43d08ad6c698fc49c72 diff --git a/manifest.uuid b/manifest.uuid index 10c399f53b..6cd1c0a46b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -26348556d824c032851e409ac510cddb55c200bf \ No newline at end of file +53fff7d1f2f829010a2641c7738538b3155da4b2 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index dfc5bdef1d..d99a76bb36 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.177 2007/03/27 12:04:05 drh Exp $ +** $Id: insert.c,v 1.178 2007/03/28 18:04:10 drh Exp $ */ #include "sqliteInt.h" @@ -1498,16 +1498,20 @@ static int xferOptimization( } sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead); emptySrcTest = sqlite3VdbeAddOp(v, OP_Rewind, iSrc, 0); - memRowid = pParse->nMem++; - sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0); - sqlite3VdbeAddOp(v, OP_MemStore, memRowid, 1); - addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - addr2 = sqlite3VdbeAddOp(v, OP_NotExists, iDest, 0); - sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, - "PRIMARY KEY must be unique", P3_STATIC); - sqlite3VdbeJumpHere(v, addr2); - autoIncStep(pParse, counterMem); + if( pDest->iPKey>=0 ){ + memRowid = pParse->nMem++; + sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0); + sqlite3VdbeAddOp(v, OP_MemStore, memRowid, 1); + addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0); + sqlite3VdbeAddOp(v, OP_Dup, 0, 0); + addr2 = sqlite3VdbeAddOp(v, OP_NotExists, iDest, 0); + sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, + "PRIMARY KEY must be unique", P3_STATIC); + sqlite3VdbeJumpHere(v, addr2); + autoIncStep(pParse, counterMem); + }else{ + addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0); + } sqlite3VdbeAddOp(v, OP_RowData, iSrc, 0); sqlite3VdbeOp3(v, OP_Insert, iDest, OPFLAG_NCHANGE|OPFLAG_LASTROWID, pDest->zName, 0); diff --git a/test/speed2.test b/test/speed2.test index a7098100f9..9d62bb80f7 100644 --- a/test/speed2.test +++ b/test/speed2.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script is measuring executing speed. # -# $Id: speed2.test,v 1.3 2007/03/27 12:04:06 drh Exp $ +# $Id: speed2.test,v 1.4 2007/03/28 18:04:10 drh Exp $ # set testdir [file dirname $argv0] @@ -111,7 +111,7 @@ for {set i 0} {$i<50} {incr i} { set upr [expr {($i+10)*100}] append sql "SELECT count(*), avg(b) FROM t1 WHERE b>=$lwr AND b<$upr;" } -speed_trial speed2-select1 [expr {50*50000}] row $sql +speed_trial speed2-select1a [expr {50*50000}] row $sql # 50 SELECTs on an LIKE comparison. There is no index so a full # table scan is required. @@ -121,7 +121,31 @@ for {set i 0} {$i<50} {incr i} { append sql \ "SELECT count(*), avg(b) FROM t1 WHERE c LIKE '%[number_name $i]%';" } -speed_trial speed2-select2 [expr {50*50000}] row $sql +speed_trial speed2-select2a [expr {50*50000}] row $sql + +# Vacuum +speed_trial speed2-vacuum1 100000 row VACUUM + +# 50 SELECTs on an integer comparison. There is no index so +# a full table scan is required. +# +set sql {} +for {set i 0} {$i<50} {incr i} { + set lwr [expr {$i*100}] + set upr [expr {($i+10)*100}] + append sql "SELECT count(*), avg(b) FROM t1 WHERE b>=$lwr AND b<$upr;" +} +speed_trial speed2-select1b [expr {50*50000}] row $sql + +# 50 SELECTs on an LIKE comparison. There is no index so a full +# table scan is required. +# +set sql {} +for {set i 0} {$i<50} {incr i} { + append sql \ + "SELECT count(*), avg(b) FROM t1 WHERE c LIKE '%[number_name $i]%';" +} +speed_trial speed2-select2b [expr {50*50000}] row $sql # Create indices # @@ -142,7 +166,7 @@ for {set i 0} {$i<5000} {incr i} { set upr [expr {($i+10)*100}] append sql "SELECT count(*), avg(b) FROM t1 WHERE b>=$lwr AND b<$upr;" } -speed_trial speed2-select3 5000 stmt $sql +speed_trial speed2-select3a 5000 stmt $sql # 100000 random SELECTs against rowid. # @@ -151,7 +175,7 @@ for {set i 1} {$i<=100000} {incr i} { set id [expr {int(rand()*50000)+1}] append sql "SELECT c=='hi' FROM t1 WHERE rowid=$id;\n" } -speed_trial speed2-select4 100000 row $sql +speed_trial speed2-select4a 100000 row $sql # 100000 random SELECTs against a unique indexed column. # @@ -160,7 +184,7 @@ for {set i 1} {$i<=100000} {incr i} { set id [expr {int(rand()*50000)+1}] append sql "SELECT c FROM t1 WHERE a=$id;" } -speed_trial speed2-select5 100000 row $sql +speed_trial speed2-select5a 100000 row $sql # 50000 random SELECTs against an indexed column text column # @@ -168,10 +192,48 @@ set sql {} db eval {SELECT c FROM t1 ORDER BY random() LIMIT 50000} { append sql "SELECT c FROM t1 WHERE c='$c';" } -speed_trial speed2-select6 50000 row $sql +speed_trial speed2-select6a 50000 row $sql # Vacuum -speed_trial speed2-vacuum 100000 row VACUUM +speed_trial speed2-vacuum2 100000 row VACUUM + + +# 5000 SELECTs on an integer comparison where the integer is +# indexed. +# +set sql {} +for {set i 0} {$i<5000} {incr i} { + set lwr [expr {$i*100}] + set upr [expr {($i+10)*100}] + append sql "SELECT count(*), avg(b) FROM t1 WHERE b>=$lwr AND b<$upr;" +} +speed_trial speed2-select3b 5000 stmt $sql + +# 100000 random SELECTs against rowid. +# +set sql {} +for {set i 1} {$i<=100000} {incr i} { + set id [expr {int(rand()*50000)+1}] + append sql "SELECT c=='hi' FROM t1 WHERE rowid=$id;\n" +} +speed_trial speed2-select4b 100000 row $sql + +# 100000 random SELECTs against a unique indexed column. +# +set sql {} +for {set i 1} {$i<=100000} {incr i} { + set id [expr {int(rand()*50000)+1}] + append sql "SELECT c FROM t1 WHERE a=$id;" +} +speed_trial speed2-select5b 100000 row $sql + +# 50000 random SELECTs against an indexed column text column +# +set sql {} +db eval {SELECT c FROM t1 ORDER BY random() LIMIT 50000} { + append sql "SELECT c FROM t1 WHERE c='$c';" +} +speed_trial speed2-select6b 50000 row $sql # 5000 updates of ranges where the field being compared is indexed. #