]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improve performance of multi-field sorts where the first field has a low cardinality.
authordan <dan@noemail.net>
Mon, 30 Mar 2015 12:06:26 +0000 (12:06 +0000)
committerdan <dan@noemail.net>
Mon, 30 Mar 2015 12:06:26 +0000 (12:06 +0000)
FossilOrigin-Name: 601e7b6b8e6bfabda03b70f75094c9014e3a3c49

manifest
manifest.uuid
src/vdbe.h
src/vdbeaux.c
src/vdbesort.c

index a3ffa9b4e02045d0b30c888cd50f9caae1ed7f3e..a7a78bf354ace9c7e6070186927fbee3a7ed9f40 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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
index 698dbf4147b5b9ed6dd7def763d58b0822778e76..2a8f64fa3a4ef27f02d3943d48a38fdf3f889637 100644 (file)
@@ -1 +1 @@
-b58191e91736b1d978db4127f22867dfe2302f7c
\ No newline at end of file
+601e7b6b8e6bfabda03b70f75094c9014e3a3c49
\ No newline at end of file
index b715241b4141220a5c1e2b1c07a60c24e4ac6cc7..bb597b68d7d20015350233d947c00feb4f506d0f 100644 (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*);
index 9c5d9acca9b130882d2c6995e6c693f730fe757f..1c10bab0b81c5846f0e6b68ec5d2c8d486434f9e 100644 (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;
         }
index b6483b9ee7fe5650fa2239533334029a9213e9eb..547dce2e65f3a117e52f0de12d1cac11c0af2828 100644 (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;