Add a way for virtual tables to return the expected number of rows for a scan (not just the overall cost) to SQLite. Have the rtree module make use of this.
FossilOrigin-Name: 5a3cfd747a85480d215784817c3821d87ecfa2f7
This commit is contained in:
+18
-5
@@ -5290,10 +5290,22 @@ struct sqlite3_module {
|
||||
** the correct order to satisfy the ORDER BY clause so that no separate
|
||||
** sorting step is required.
|
||||
**
|
||||
** ^The estimatedCost value is an estimate of the cost of doing the
|
||||
** particular lookup. A full scan of a table with N entries should have
|
||||
** a cost of N. A binary search of a table of N entries should have a
|
||||
** cost of approximately log(N).
|
||||
** ^The estimatedCost value is an estimate of the cost of a particular
|
||||
** strategy. A cost of N indicates that the cost of the strategy is similar
|
||||
** to a linear scan of an SQLite table with N rows. A cost of log(N)
|
||||
** indicates that the expense of the operation is similar to that of a
|
||||
** binary search on a unique indexed field of an SQLite table with N rows.
|
||||
**
|
||||
** ^The estimatedRows value is an estimate of the number of rows that
|
||||
** will be returned by the strategy.
|
||||
**
|
||||
** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
|
||||
** structure for SQLite version 3.8.2. If a virtual table extension is
|
||||
** used with an SQLite version earlier than 3.8.2, the results of attempting
|
||||
** to read or write the estimatedRows field are undefined (but are likely
|
||||
** to included crashing the application). The estimatedRows field should
|
||||
** therefore only be used if [sqlite3_libversion_number()] returns a
|
||||
** value greater than or equal to 3008002.
|
||||
*/
|
||||
struct sqlite3_index_info {
|
||||
/* Inputs */
|
||||
@@ -5318,7 +5330,8 @@ struct sqlite3_index_info {
|
||||
char *idxStr; /* String, possibly obtained from sqlite3_malloc */
|
||||
int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
|
||||
int orderByConsumed; /* True if output is already ordered */
|
||||
double estimatedCost; /* Estimated cost of using this index */
|
||||
double estimatedCost; /* Estimated cost of using this index */
|
||||
sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+3
-2
@@ -1978,6 +1978,7 @@ static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){
|
||||
sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr);
|
||||
sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed);
|
||||
sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost);
|
||||
sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows);
|
||||
}
|
||||
#else
|
||||
#define TRACE_IDX_INPUTS(A)
|
||||
@@ -4787,6 +4788,7 @@ static int whereLoopAddVirtual(
|
||||
pIdxInfo->needToFreeIdxStr = 0;
|
||||
pIdxInfo->orderByConsumed = 0;
|
||||
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
|
||||
pIdxInfo->estimatedRows = 25;
|
||||
rc = vtabBestIndex(pParse, pTab, pIdxInfo);
|
||||
if( rc ) goto whereLoopAddVtab_exit;
|
||||
pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
|
||||
@@ -4846,8 +4848,7 @@ static int whereLoopAddVirtual(
|
||||
&& pIdxInfo->orderByConsumed);
|
||||
pNew->rSetup = 0;
|
||||
pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
|
||||
/* TUNING: Every virtual table query returns 25 rows */
|
||||
pNew->nOut = 46; assert( 46==sqlite3LogEst(25) );
|
||||
pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
|
||||
whereLoopInsert(pBuilder, pNew);
|
||||
if( pNew->u.vtab.needFree ){
|
||||
sqlite3_free(pNew->u.vtab.idxStr);
|
||||
|
||||
Reference in New Issue
Block a user