diff options
author | drh <drh@noemail.net> | 2018-09-17 20:47:38 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2018-09-17 20:47:38 +0000 |
commit | 40b4e7a6923cde8c5ab0b8148c3b07bbf4414e8c (patch) | |
tree | 0cc3a205e0d0addd74ec83e3af4d0001adc61025 /src | |
parent | d4cb09e3d26a2b507bf781b168922da81bb54b53 (diff) | |
download | sqlite-40b4e7a6923cde8c5ab0b8148c3b07bbf4414e8c.tar.gz sqlite-40b4e7a6923cde8c5ab0b8148c3b07bbf4414e8c.zip |
Further optimizations to the UPDATE logic to avoid making changes to partial
indexes if none of the columns mentioned in the WHERE clause are modified by
the UPDATE.
FossilOrigin-Name: d1365a5bf0ee2f145427b81d2a593f539c3ad4705d579478703c1f65ae5f80bf
Diffstat (limited to 'src')
-rw-r--r-- | src/update.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/update.c b/src/update.c index 9e76c445e..dd2b05c3e 100644 --- a/src/update.c +++ b/src/update.c @@ -82,7 +82,9 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ /* ** Check to see if column iCol of index pIdx references any of the ** columns defined by aXRef and chngRowid. Return true if it does -** and false if not. +** and false if not. This is an optimization. False-positives are a +** performance degradation, but false-negatives can result in a corrupt +** index and incorrect answers. ** ** aXRef[j] will be non-negative if column j of the original table is ** being updated. chngRowid will be true if the rowid of the table is @@ -107,6 +109,28 @@ static int indexColumnIsBeingUpdated( } /* +** Check to see if index pIdx is a partial index whose conditional +** expression might change values due to an UPDATE. Return true if +** the index is subject to change and false if the index is guaranteed +** to be unchanged. This is an optimization. False-positives are a +** performance degradation, but false-negatives can result in a corrupt +** index and incorrect answers. +** +** aXRef[j] will be non-negative if column j of the original table is +** being updated. chngRowid will be true if the rowid of the table is +** being updated. +*/ +static int indexWhereClauseMightChange( + Index *pIdx, /* The index to check */ + int *aXRef, /* aXRef[j]>=0 if column j is being updated */ + int chngRowid /* true if the rowid is being updated */ +){ + if( pIdx->pPartIdxWhere==0 ) return 0; + return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere, + aXRef, chngRowid); +} + +/* ** Process an UPDATE statement. ** ** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL; @@ -332,7 +356,9 @@ void sqlite3Update( */ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int reg; - if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){ + if( chngKey || hasFK>1 || pIdx==pPk + || indexWhereClauseMightChange(pIdx,aXRef,chngRowid) + ){ reg = ++pParse->nMem; pParse->nMem += pIdx->nColumn; }else{ |