Improve performance of multi-field sorts where the first field has a low cardinality.

FossilOrigin-Name: 601e7b6b8e6bfabda03b70f75094c9014e3a3c49
This commit is contained in:
dan 2015-03-30 12:06:26 +00:00
parent d2e1191929
commit 7004f3f6a3
5 changed files with 39 additions and 15 deletions

View File

@ -1,5 +1,5 @@
C Remove\ssome\sunnecessary\scode\sfrom\svdbesort.c.
D 2015-03-30T09:58:38.613
C Improve\sperformance\sof\smulti-field\ssorts\swhere\sthe\sfirst\sfield\shas\sa\slow\scardinality.
D 2015-03-30T12:06:26.995
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -294,13 +294,13 @@ F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e
F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec
F src/vdbe.c bbfede5a8a6908b3ddcd55fdb0b2301288dd4754
F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3
F src/vdbe.h 7e538ecf47dccb307ea2d087c3ddc2dd8d70e79d
F src/vdbeInt.h 9cbaa84f53ddd2d09a0cf61a94337a3a035d08a0
F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75
F src/vdbeaux.c 413dc496248ac18eb0c19e35e86bb1ffd47b8907
F src/vdbeaux.c a20504ae52392459fa08402fda3f195f19d7c79d
F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9
F src/vdbesort.c f283b28d9d1bbaf9c4467c1275ab2146ed868ec9
F src/vdbesort.c 7b3684665ea51d642b0e664fa4d0b0d08d61d80c
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
F src/vtab.c 62d49237bd8f3be4863815a39387b0f9897fa5e1
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
@ -1247,7 +1247,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 24fe9f25d64ee516633fed1ae7ebc21554aa69ca
R 7cd5cef35d63d5a82a586382f49d8e50
P b58191e91736b1d978db4127f22867dfe2302f7c
R ce44a3d54ad53a02b61fed80311cecef
U dan
Z 51fc974a93f39baea754c6fb429251e1
Z 8753c6822202b0898d8492105ecdb751

View File

@ -1 +1 @@
b58191e91736b1d978db4127f22867dfe2302f7c
601e7b6b8e6bfabda03b70f75094c9014e3a3c49

View File

@ -213,6 +213,7 @@ int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int);
UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);

View File

@ -3585,7 +3585,7 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the
** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db).
*/
static int vdbeRecordCompareWithSkip(
int sqlite3VdbeRecordCompareWithSkip(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2, /* Right key */
int bSkip /* If true, skip the first field */
@ -3771,7 +3771,7 @@ int sqlite3VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2 /* Right key */
){
return vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
}
@ -3859,7 +3859,7 @@ static int vdbeRecordCompareInt(
}else if( pPKey2->nField>1 ){
/* The first fields of the two keys are equal. Compare the trailing
** fields. */
res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
}else{
/* The first fields of the two keys are equal and there are no trailing
** fields. Return pPKey2->default_rc in this case. */
@ -3907,7 +3907,7 @@ static int vdbeRecordCompareString(
res = nStr - pPKey2->aMem[0].n;
if( res==0 ){
if( pPKey2->nField>1 ){
res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
}else{
res = pPKey2->default_rc;
}

View File

@ -749,6 +749,25 @@ static int vdbePmaReaderInit(
return rc;
}
/*
** A version of vdbeSorterCompare() that assumes that it has already been
** determined that the first field of key1 is equal to the first field of
** key2.
*/
static int vdbeSorterCompareTail(
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
UnpackedRecord *r2 = pTask->pUnpacked;
if( *pbKey2Cached==0 ){
sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
*pbKey2Cached = 1;
}
return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1);
}
/*
** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2,
** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences
@ -805,7 +824,9 @@ static int vdbeSorterCompareText(
if( res==0 ){
if( pTask->pSorter->pKeyInfo->nField>1 ){
res = vdbeSorterCompare(pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2);
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
}
}else{
if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
@ -872,7 +893,9 @@ static int vdbeSorterCompareInt(
if( res==0 ){
if( pTask->pSorter->pKeyInfo->nField>1 ){
res = vdbeSorterCompare(pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2);
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
}
}else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
res = res * -1;