When a cursor points at the last entry of an intkey btree after an insert, leave it there (instead of moving it to the tree root node). This speeds up statements of the form "INSERT INTO ... SELECT ..." that use auto-generated rowids. (CVS 6592)

FossilOrigin-Name: 9950c0a79c82eb7d8495b0b1a8fe117d566e2387
This commit is contained in:
danielk1977 2009-05-02 10:03:09 +00:00
parent 9c3acf3cfe
commit 3f632d5bd2
3 changed files with 55 additions and 14 deletions

View File

@ -1,5 +1,5 @@
C Do\snot\sreset\sthe\scursor\sbefore\sseeking\sit\sin\ssqlite3BtreeInsert().\sThis\sspeeds\sup\sINSERT\soperations\sthat\suse\sauto-generated\srowid\svalues.\s(CVS\s6591)
D 2009-05-02T07:36:50
C When\sa\scursor\spoints\sat\sthe\slast\sentry\sof\san\sintkey\sbtree\safter\san\sinsert,\sleave\sit\sthere\s(instead\sof\smoving\sit\sto\sthe\stree\sroot\snode).\sThis\sspeeds\sup\sstatements\sof\sthe\sform\s"INSERT\sINTO\s...\sSELECT\s..."\sthat\suse\sauto-generated\srowids.\s(CVS\s6592)
D 2009-05-02T10:03:09
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -106,7 +106,7 @@ F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
F src/backup.c 0082d0e5a63f04e88faee0dff0a7d63d3e92a78d
F src/bitvec.c ef370407e03440b0852d05024fb016b14a471d3d
F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
F src/btree.c 1201cba9e4ccd029a2b88431d14e315c086af6ba
F src/btree.c 64ad8841aefce2ba0cb3b138e5fe8669ce5fa6db
F src/btree.h 99fcc7e8c4a1e35afe271bcb38de1a698dfc904e
F src/btreeInt.h df64030d632f8c8ac217ed52e8b6b3eacacb33a5
F src/build.c a079f965feea2d0b469b293e09cd0ac41be1272f
@ -727,7 +727,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P 7d2b80c7addc2d03d49647da9c6df9113f01349d
R be37f24bb5752583479cd908d65ba960
P 20c4acc291def33980f584f882c76e85ee1c8238
R 473bd4e478192dc26a9afe58e69a17f0
U danielk1977
Z 771348bde250b0527ce1a0ce0c034f60
Z 5fda7c8bdbaa8fda519ae98860016fe1

View File

@ -1 +1 @@
20c4acc291def33980f584f882c76e85ee1c8238
9950c0a79c82eb7d8495b0b1a8fe117d566e2387

View File

@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.604 2009/05/02 07:36:50 danielk1977 Exp $
** $Id: btree.c,v 1.605 2009/05/02 10:03:09 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
@ -3921,6 +3921,22 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
assert( cursorHoldsMutex(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
/* If the cursor already points to the last entry, this is a no-op. */
if( CURSOR_VALID==pCur->eState && pCur->atLast ){
#ifdef SQLITE_DEBUG
/* This block serves to assert() that the cursor really does point
** to the last entry in the b-tree. */
int ii;
for(ii=0; ii<pCur->iPage; ii++){
assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
}
assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 );
assert( pCur->apPage[pCur->iPage]->leaf );
#endif
return SQLITE_OK;
}
rc = moveToRoot(pCur);
if( rc==SQLITE_OK ){
if( CURSOR_INVALID==pCur->eState ){
@ -6210,17 +6226,42 @@ int sqlite3BtreeInsert(
assert( pPage->leaf );
}
rc = insertCell(pPage, idx, newCell, szNew, 0, 0);
if( rc==SQLITE_OK ){
rc = balance(pCur, 1);
}
assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );
/* If no error has occured, call balance() to deal with any overflow and
** move the cursor to point at the root of the table (since balance may
** have rearranged the table in such a way as to invalidate BtCursor.apPage[]
** or BtCursor.aiIdx[]).
**
** Except, if all of the following are true, do nothing:
**
** * Inserting the new cell did not cause overflow,
**
** * Before inserting the new cell the cursor was pointing at the
** largest key in an intkey B-Tree, and
**
** * The key value associated with the new cell is now the largest
** in the B-Tree.
**
** In this case the cursor can be safely left pointing at the (new)
** largest key value in the B-Tree. Doing so speeds up inserting a set
** of entries with increasing integer key values via a single cursor
** (comes up with "INSERT INTO ... SELECT ..." statements), as
** the next insert operation is not required to seek the cursor.
*/
if( rc==SQLITE_OK
&& (pPage->nOverflow || !pCur->atLast || loc>=0 || !pCur->apPage[0]->intKey)
){
rc = balance(pCur, 1);
if( rc==SQLITE_OK ){
moveToRoot(pCur);
}
}
/* Must make sure nOverflow is reset to zero even if the balance()
** fails. Internal data structure corruption will result otherwise. */
pCur->apPage[pCur->iPage]->nOverflow = 0;
if( rc==SQLITE_OK ){
moveToRoot(pCur);
}
end_insert:
return rc;
}