]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Performance improvement: Avoid unnecessary seeks on REPLACE INTO for a
authordrh <drh@noemail.net>
Fri, 8 Nov 2013 16:54:56 +0000 (16:54 +0000)
committerdrh <drh@noemail.net>
Fri, 8 Nov 2013 16:54:56 +0000 (16:54 +0000)
WITHOUT ROWID table.

FossilOrigin-Name: fd11afa5f5c853dcac2290444b581a3fe1d4332d

manifest
manifest.uuid
src/delete.c
src/insert.c
src/sqliteInt.h

index e7d399acd1a4ef804781a60b18fa2c63f2768a8e..6bbae7bba99ee12d9cf38d764a82f003f53fb0a3 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Performance\simprovements:\nAvoid\sunnecessary\sseeks\swhen\sdoing\sa\ssingle-row\sUPDATE\son\sa\sWITHOUT\sROWID\ntable.
-D 2013-11-08T15:19:46.383
+C Performance\simprovement:\sAvoid\sunnecessary\sseeks\son\sREPLACE\sINTO\sfor\sa\nWITHOUT\sROWID\stable.
+D 2013-11-08T16:54:56.609
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in d12e4455cf7a36e42d3949876c1c3b88ff70867a
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -173,7 +173,7 @@ F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
 F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
-F src/delete.c fb896d68bae9a5ee3459c60d8ed929a2b41f7afb
+F src/delete.c ddb92f44595366c4817e576b5f11cad5a915c3ef
 F src/expr.c e7bbe3c6916e141f27a28655d3cf325b817695e4
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 5370840745f01f11fb219922d8e99a48ff92fbeb
@@ -182,7 +182,7 @@ F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759
 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
-F src/insert.c 11d577c152a3304a078d508e5a65031904ed61e7
+F src/insert.c b3218fa5dceeb563485113eff8e1d4c3c59160b0
 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
@@ -223,7 +223,7 @@ F src/shell.c 03d8d9b4052430343ff30d646334621f980f1202
 F src/sqlite.h.in a8cad179541b8d171fed425a737084702ef462ef
 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h b4311956d26be8036f5feb2f1c904c313979ea17
+F src/sqliteInt.h 3da1940a2ba05a663e9016d57f1ea1f79ffcb03e
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -1135,7 +1135,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 3c566e41e4c9c66960cc5a3ddee8556835237999
-R cbe50e39428754e7aa6f05505b294390
+P 6f187a0fb1b09ebc4732c4afbf3c813f82e069f1
+R eedb71726af8e12f0f13d18d7fd22009
 U drh
-Z 2b1321d582e3f35ab93369db1373861d
+Z 047e6bb9b5b607bfaacf5c7e4c685d04
index 3cdcec40aeba2ef7541633f6d8a85ce72330fe4c..7a0daf81878445bf215a4a7bf94469122f542932 100644 (file)
@@ -1 +1 @@
-6f187a0fb1b09ebc4732c4afbf3c813f82e069f1
\ No newline at end of file
+fd11afa5f5c853dcac2290444b581a3fe1d4332d
\ No newline at end of file
index a1b626ef4af4c77cd63c5c8d1165090775d4ea2a..4fb394659581a6c5869fa9e26e36af5f1064dddb 100644 (file)
@@ -408,7 +408,7 @@ void sqlite3DeleteFrom(
 
     /* Delete the row */
     sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
-                             iPk, 0, 1, OE_Default);
+                             iPk, 0, 1, OE_Default, 0);
 
     /* End of the delete loop */
     sqlite3VdbeAddOp2(v, OP_Next, iEph, addr+1);
@@ -472,7 +472,7 @@ void sqlite3DeleteFrom(
     {
       int count = (pParse->nested==0);    /* True to count changes */
       sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
-                               iRowid, 1, count, OE_Default);
+                               iRowid, 1, count, OE_Default, 0);
     }
 
     /* End of the delete loop */
@@ -551,7 +551,8 @@ void sqlite3GenerateRowDelete(
   int iPk,           /* First memory cell containing the PRIMARY KEY */
   i16 nPk,           /* Number of PRIMARY KEY memory cells */
   u8 count,          /* If non-zero, increment the row change counter */
-  u8 onconf          /* Default ON CONFLICT policy for triggers */
+  u8 onconf,         /* Default ON CONFLICT policy for triggers */
+  u8 bNoSeek         /* iDataCur is already pointing to the row to delete */
 ){
   Vdbe *v = pParse->pVdbe;        /* Vdbe */
   int iOld = 0;                   /* First register in OLD.* array */
@@ -568,7 +569,7 @@ void sqlite3GenerateRowDelete(
   ** not attempt to delete it or fire any DELETE triggers.  */
   iLabel = sqlite3VdbeMakeLabel(v);
   opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
-  sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
+  if( !bNoSeek ) sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
  
   /* If there are any triggers to fire, allocate a range of registers to
   ** use for the old.* references in the triggers.  */
@@ -672,18 +673,17 @@ void sqlite3GenerateRowIndexDelete(
   Index *pPk;        /* PRIMARY KEY index, or NULL for rowid tables */
 
   v = pParse->pVdbe;
-  VdbeModuleComment((v, "BEGIN: GenRowIdxDel(%d,%d)", iDataCur, iIdxCur));
   pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
   for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
     assert( iIdxCur+i!=iDataCur || pPk==pIdx );
     if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
     if( pIdx==pPk ) continue;
+    VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
     r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, &iPartIdxLabel);
     sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
                       pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
     sqlite3VdbeResolveLabel(v, iPartIdxLabel);
   }
-  VdbeModuleComment((v, "END: GenRowIdxDel()"));
 }
 
 /*
index d789d298c9c58835f7a0c8cc5e74ee939fb850a7..7235370a53a70cf6553d0b6dac73edeaa86b6c4c 100644 (file)
@@ -1408,7 +1408,7 @@ void sqlite3GenerateConstraintChecks(
         if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
           sqlite3MultiWrite(pParse);
           sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
-                                   regNewData, 1, 0, OE_Replace);
+                                   regNewData, 1, 0, OE_Replace, 1);
         }else if( pTab->pIndex ){
           sqlite3MultiWrite(pParse);
           sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0);
@@ -1498,11 +1498,11 @@ void sqlite3GenerateConstraintChecks(
     }
     
     /* Check to see if the new index entry will be unique */
-    regR = sqlite3GetTempRange(pParse, nPkField);
     sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
                          regIdx, pIdx->nKeyCol);
 
     /* Generate code to handle collisions */
+    regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField);
     if( HasRowid(pTab) ){
       sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
       /* Conflict only if the rowid of the existing index entry
@@ -1514,7 +1514,7 @@ void sqlite3GenerateConstraintChecks(
       int x;
       /* Extract the PRIMARY KEY from the end of the index entry and
       ** store it in registers regR..regR+nPk-1 */
-      if( isUpdate || onError==OE_Replace ){
+      if( (isUpdate || onError==OE_Replace) && pIdx!=pPk ){
         for(i=0; i<pPk->nKeyCol; i++){
           x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
           sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
@@ -1547,7 +1547,6 @@ void sqlite3GenerateConstraintChecks(
         }
       }
     }
-    sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
 
     /* Generate code that executes if the new index entry is not unique */
     assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
@@ -1571,13 +1570,14 @@ void sqlite3GenerateConstraintChecks(
           pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
         }
         sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
-                                 regR, nPkField, 0, OE_Replace);
+                                 regR, nPkField, 0, OE_Replace, pIdx==pPk);
         seenReplace = 1;
         break;
       }
     }
     sqlite3VdbeResolveLabel(v, addrUniqueOk);
-    sqlite3ReleaseTempRange(pParse, regR, nPkField);
+    sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
+    if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
   }
   if( ipkTop ){
     sqlite3VdbeAddOp2(v, OP_Goto, 0, ipkTop+1);
index 934ba3c965f3b020afc7db76b27652e4f910df24..0ae55edf3d071e1dd3b3879c6f36eb2044dd0394 100644 (file)
@@ -2930,7 +2930,7 @@ int sqlite3ExprCanBeNull(const Expr*);
 void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
 int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
 int sqlite3IsRowid(const char*);
-void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8);
+void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
 void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
 int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
 void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,