1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-16 23:02:26 +03:00

Scan an index instead of a table for "SELECT count(*) FROM <tbl>" queries. Because an index is usually smaller than a table on disk, this saves some IO. (CVS 6315)

FossilOrigin-Name: 294ba6f743c9132dce0e73da480bd3c2071e7239
This commit is contained in:
danielk1977
2009-02-23 17:33:49 +00:00
parent 699b3d4f89
commit e2d7b24d08
9 changed files with 82 additions and 33 deletions

View File

@@ -16,7 +16,7 @@
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.371 2009/02/23 16:52:08 drh Exp $
** $Id: where.c,v 1.372 2009/02/23 17:33:50 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -1715,15 +1715,15 @@ static double bestVirtualIndex(
** * Whether or not there must be separate lookups in the
** index and in the main table.
**
** If there was an INDEXED BY clause attached to the table in the SELECT
** statement, then this function only considers plans using the
** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in
** the SQL statement, then this function only considers plans using the
** named index. If one cannot be found, then the returned cost is
** SQLITE_BIG_DBL. If a plan can be found that uses the named index,
** then the cost is calculated in the usual way.
**
** If a NOT INDEXED clause was attached to the table in the SELECT
** statement, then no indexes are considered. However, the selected
** plan may still take advantage of the tables built-in rowid
** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table
** in the SELECT statement, then no indexes are considered. However, the
** selected plan may still take advantage of the tables built-in rowid
** index.
*/
static void bestIndex(
@@ -2035,6 +2035,21 @@ static void bestIndex(
}
}
if( pCost->plan.wsFlags==0 && pSrc->colUsed==0 && pSrc->usesRowid==0 ){
Index *pSmallest = 0;
assert( pSrc->pIndex==0 );
for(pProbe=pSrc->pTab->pIndex; pProbe; pProbe=pProbe->pNext){
if( !pSmallest || pProbe->nColumn<pSmallest->nColumn ){
pSmallest = pProbe;
}
}
if( pSmallest && pSmallest->nColumn<pSrc->pTab->nCol ){
assert( pCost->plan.nEq==0 );
pCost->plan.u.pIdx = pSmallest;
pCost->plan.wsFlags = WHERE_COLUMN_RANGE|WHERE_IDX_ONLY;
}
}
/* Report the best result
*/
pCost->plan.wsFlags |= eqTermMask;