mirror of https://github.com/sqlite/sqlite
Performance improvement: Avoid unnecessary seeks on REPLACE INTO for a
WITHOUT ROWID table. FossilOrigin-Name: fd11afa5f5c853dcac2290444b581a3fe1d4332d
This commit is contained in:
parent
fc8d4f96b4
commit
392ee21d1a
16
manifest
16
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
|
||||
|
|
|
@ -1 +1 @@
|
|||
6f187a0fb1b09ebc4732c4afbf3c813f82e069f1
|
||||
fd11afa5f5c853dcac2290444b581a3fe1d4332d
|
12
src/delete.c
12
src/delete.c
|
@ -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()"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
12
src/insert.c
12
src/insert.c
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue