Performance improvement: Avoid unnecessary seeks on REPLACE INTO for a

WITHOUT ROWID table.

FossilOrigin-Name: fd11afa5f5c853dcac2290444b581a3fe1d4332d
This commit is contained in:
drh 2013-11-08 16:54:56 +00:00
parent fc8d4f96b4
commit 392ee21d1a
5 changed files with 22 additions and 22 deletions

View File

@ -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

View File

@ -1 +1 @@
6f187a0fb1b09ebc4732c4afbf3c813f82e069f1
fd11afa5f5c853dcac2290444b581a3fe1d4332d

View 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()"));
}
/*

View 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);

View 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,