1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-10 01:02:56 +03:00

Completely remove the iScanRatio field. The PRAGMA index_list(TABLE) command

shows the estimated row size in the forth column.  It also generates a row
for the table with an index name of NULL.  The query planner still does not
take row size estimates into account - that is the next step.

FossilOrigin-Name: 8b4aa0c7a2122bbe60432edadf27e490e31ec987
This commit is contained in:
drh
2013-10-05 19:18:00 +00:00
parent 0af62b015a
commit e13e9f54b0
8 changed files with 50 additions and 64 deletions

View File

@@ -1,5 +1,5 @@
C Improvements\sto\sthe\sLogEst\scommand-line\stool\sused\sto\sconvert\sbetween\nordinary\snumbers\sand\sthe\sLogEst\srepresentation. C Completely\sremove\sthe\siScanRatio\sfield.\s\sThe\sPRAGMA\sindex_list(TABLE)\scommand\nshows\sthe\sestimated\srow\ssize\sin\sthe\sforth\scolumn.\s\sIt\salso\sgenerates\sa\srow\nfor\sthe\stable\swith\san\sindex\sname\sof\sNULL.\s\sThe\squery\splanner\sstill\sdoes\snot\ntake\srow\ssize\sestimates\sinto\saccount\s-\sthat\sis\sthe\snext\sstep.
D 2013-10-05T18:32:30.669 D 2013-10-05T19:18:00.706
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -157,7 +157,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083 F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083
F src/analyze.c c692855a5ba351ea2eddd916f7608fc28f09aa68 F src/analyze.c 9f71f38700202b9c28153185b9d06fd4fe489cc9
F src/attach.c 0a17c9364895316ca4f52d06a97a72c0af1ae8b3 F src/attach.c 0a17c9364895316ca4f52d06a97a72c0af1ae8b3
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3 F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3
@@ -166,7 +166,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 5ccbbaed7a32ba774306f610da4ab4f3e5348294 F src/btree.c 5ccbbaed7a32ba774306f610da4ab4f3e5348294
F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf
F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0
F src/build.c f92f1cd23ddb07b2aa84e21199bab97ad2da1144 F src/build.c 3278345550d2b6cd9348d297f7acd22d900429eb
F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
@@ -210,18 +210,18 @@ F src/parse.y a97566d6da75075589a7c716d1bda14b586cf8da
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63 F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63
F src/pragma.c 07814efdbf815356dafd4bfa4c21f527edbb0150 F src/pragma.c c9a867f6f96934e91d3a07d72d1b8d61c9963008
F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f
F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b
F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68
F src/resolve.c 7459801d02997b07e8b8da85ef255392ba1d022b F src/resolve.c 7459801d02997b07e8b8da85ef255392ba1d022b
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c 6131008151ddc09bd04ceda98c3fcb8a36edacdd F src/select.c 13be733297f415b388444a2e296d23569cd83b8a
F src/shell.c 5ee50ca3e35453bbd6ccdf1bdd0f6bbe9738e9fb F src/shell.c 5ee50ca3e35453bbd6ccdf1bdd0f6bbe9738e9fb
F src/sqlite.h.in ec40aa958a270416fb04b4f72210357bf163d2c5 F src/sqlite.h.in ec40aa958a270416fb04b4f72210357bf163d2c5
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 75a6f6b26a91703672d62bd8df3bede2e6747e3b F src/sqliteInt.h 5dbfc960fb39dbb55ba16697f453b03cd759b04a
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -290,7 +290,7 @@ F src/vtab.c 5a423b042eb1402ef77697d03d6a67378d97bc8d
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74
F src/where.c 7b98d09e0e13179a8aeed38578434936369aa5c2 F src/where.c 72c6c205e53ae72d2d235705bb2b040d70fff2e2
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -1121,7 +1121,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P 66c4a251d61582b47d5cbe50cbca160a9209bd06 P 5252aeb61988e511dcf8d527fa81e51a5c9385f9
R 816e9739b4c9fe149e1a1ff9e9aba52e R 0e3b98862666ae9510c1569ec248e564
U drh U drh
Z 6ff6e983ab5701c81dead21480c8edfc Z 912eec158a04027b64a47b63c711b530

View File

@@ -1 +1 @@
5252aeb61988e511dcf8d527fa81e51a5c9385f9 8b4aa0c7a2122bbe60432edadf27e490e31ec987

View File

@@ -1277,17 +1277,10 @@ static void decodeIntArray(
if( pIndex ){ if( pIndex ){
if( strcmp(z, "unordered")==0 ){ if( strcmp(z, "unordered")==0 ){
pIndex->bUnordered = 1; pIndex->bUnordered = 1;
}else if( sqlite3_strglob("r=[0-9]*", z)==0 ){ }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
int v32 = 0; int v32 = 0;
sqlite3GetInt32(z+2, &v32); sqlite3GetInt32(z+3, &v32);
if( v32>=200 ){ pIndex->szIdxRow = sqlite3LogEst(v32);
v32 = 255;
}else if( v32<=0 ){
v32 = 1;
}else{
v32 = (128*v32)/100;
}
pIndex->iScanRatio = (u8)v32;
} }
} }
} }

View File

@@ -1508,7 +1508,7 @@ static char *createTableStmt(sqlite3 *db, Table *p){
/* /*
** Estimate the total row width for a table. ** Estimate the total row width for a table.
*/ */
static unsigned estimatedTableWidth(const Table *pTab){ static void estimateTableWidth(Table *pTab){
unsigned wTable = 0; unsigned wTable = 0;
const Column *pTabCol; const Column *pTabCol;
int i; int i;
@@ -1516,15 +1516,13 @@ static unsigned estimatedTableWidth(const Table *pTab){
wTable += pTabCol->szEst; wTable += pTabCol->szEst;
} }
if( pTab->iPKey<0 ) wTable++; if( pTab->iPKey<0 ) wTable++;
return wTable; pTab->szTabRow = sqlite3LogEst(wTable*4);
} }
/* /*
** Set the iScanRatio for an index based on estimates of the average ** Estimate the average size of a row for an index.
** table row width and average index row width. Estimates are derived
** from the declared datatypes of the various columns.
*/ */
static void setIndexScanRatio(Index *pIdx, unsigned wTable){ static void estimateIndexWidth(Index *pIdx){
unsigned wIndex = 1; unsigned wIndex = 1;
int i; int i;
const Column *aCol = pIdx->pTable->aCol; const Column *aCol = pIdx->pTable->aCol;
@@ -1532,10 +1530,7 @@ static void setIndexScanRatio(Index *pIdx, unsigned wTable){
assert( pIdx->aiColumn[i]>=0 && pIdx->aiColumn[i]<pIdx->pTable->nCol ); assert( pIdx->aiColumn[i]>=0 && pIdx->aiColumn[i]<pIdx->pTable->nCol );
wIndex += aCol[pIdx->aiColumn[i]].szEst; wIndex += aCol[pIdx->aiColumn[i]].szEst;
} }
assert( 100*wIndex/wTable <= 255 ); pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
pIdx->iScanRatio = (u8)(128*wIndex/wTable);
/* printf("%s: wIndex=%d wTable=%d ratio=%d\n",
** pIdx->zName, wIndex, wTable, (100*pIdx->iScanRatio)/128); */
} }
/* /*
@@ -1588,10 +1583,10 @@ void sqlite3EndTable(
} }
#endif /* !defined(SQLITE_OMIT_CHECK) */ #endif /* !defined(SQLITE_OMIT_CHECK) */
/* Compute the iScanRatio of implied indices */ /* Estimate the average row size for the table and for all implied indices */
wTable = estimatedTableWidth(p); estimateTableWidth(p);
for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
setIndexScanRatio(pIdx, wTable); estimateIndexWidth(pIdx);
} }
/* If the db->init.busy is 1 it means we are reading the SQL off the /* If the db->init.busy is 1 it means we are reading the SQL off the
@@ -2818,9 +2813,7 @@ Index *sqlite3CreateIndex(
if( pTab->aCol[j].notNull==0 ) pIndex->uniqNotNull = 0; if( pTab->aCol[j].notNull==0 ) pIndex->uniqNotNull = 0;
} }
sqlite3DefaultRowEst(pIndex); sqlite3DefaultRowEst(pIndex);
if( pParse->pNewTable==0 ){ if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
setIndexScanRatio(pIndex, estimatedTableWidth(pTab));
}
if( pTab==pParse->pNewTable ){ if( pTab==pParse->pNewTable ){
/* This routine has been called to create an automatic index as a /* This routine has been called to create an automatic index as a

View File

@@ -1449,28 +1449,30 @@ void sqlite3Pragma(
case PragTyp_INDEX_LIST: if( zRight ){ case PragTyp_INDEX_LIST: if( zRight ){
Index *pIdx; Index *pIdx;
Table *pTab; Table *pTab;
int i;
pTab = sqlite3FindTable(db, zRight, zDb); pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){ if( pTab ){
v = sqlite3GetVdbe(pParse); v = sqlite3GetVdbe(pParse);
pIdx = pTab->pIndex; sqlite3VdbeSetNumCols(v, 4);
if( pIdx ){ pParse->nMem = 4;
int i = 0; sqlite3CodeVerifySchema(pParse, iDb);
sqlite3VdbeSetNumCols(v, 4); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
pParse->nMem = 4; sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
sqlite3CodeVerifySchema(pParse, iDb); sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "avgrowsize", SQLITE_STATIC);
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); sqlite3VdbeAddOp2(v, OP_Integer, 0, 1);
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC); sqlite3VdbeAddOp2(v, OP_Null, 0, 2);
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "r", SQLITE_STATIC); sqlite3VdbeAddOp2(v, OP_Integer, 1, 3);
while(pIdx){ sqlite3VdbeAddOp2(v, OP_Integer,
sqlite3VdbeAddOp2(v, OP_Integer, i, 1); (int)sqlite3LogEstToInt(pTab->szTabRow), 4);
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3); for(pIdx=pTab->pIndex, i=1; pIdx; pIdx=pIdx->pNext, i++){
sqlite3VdbeAddOp2(v, OP_Integer, (pIdx->iScanRatio*100+127)/128, 4); sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
++i; sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3);
pIdx = pIdx->pNext; sqlite3VdbeAddOp2(v, OP_Integer,
} (int)sqlite3LogEstToInt(pIdx->szIdxRow), 4);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
} }
} }
} }

View File

@@ -4608,9 +4608,9 @@ int sqlite3Select(
*/ */
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->bUnordered==0 if( pIdx->bUnordered==0
&& pIdx->iScanRatio<128 && pIdx->szIdxRow<pTab->szTabRow
&& pIdx->pPartIdxWhere==0 && pIdx->pPartIdxWhere==0
&& (!pBest || pIdx->iScanRatio<pBest->iScanRatio) && (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
){ ){
pBest = pIdx; pBest = pIdx;
} }

View File

@@ -1588,7 +1588,6 @@ struct Index {
int tnum; /* DB Page containing root of this index */ int tnum; /* DB Page containing root of this index */
LogEst szIdxRow; /* Estimated average row size in bytes */ LogEst szIdxRow; /* Estimated average row size in bytes */
u16 nColumn; /* Number of columns in table used by this index */ u16 nColumn; /* Number of columns in table used by this index */
u8 iScanRatio; /* Scan rate relative to the main table */
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
unsigned bUnordered:1; /* Use this index for == or IN queries only */ unsigned bUnordered:1; /* Use this index for == or IN queries only */

View File

@@ -4569,7 +4569,7 @@ static int whereLoopAddBtree(
pNew->iSortIdx = b ? iSortIdx : 0; pNew->iSortIdx = b ? iSortIdx : 0;
/* TUNING: Cost of full table scan is 3*(N + log2(N)). /* TUNING: Cost of full table scan is 3*(N + log2(N)).
** + The extra 3 factor is to encourage the use of indexed lookups ** + The extra 3 factor is to encourage the use of indexed lookups
** over full scans. */ ** over full scans. FIXME */
pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 16; pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 16;
whereLoopOutputAdjust(pWC, pNew, pSrc->iCursor); whereLoopOutputAdjust(pWC, pNew, pSrc->iCursor);
rc = whereLoopInsert(pBuilder, pNew); rc = whereLoopInsert(pBuilder, pNew);
@@ -4583,7 +4583,6 @@ static int whereLoopAddBtree(
if( b if( b
|| ( m==0 || ( m==0
&& pProbe->bUnordered==0 && pProbe->bUnordered==0
&& pProbe->iScanRatio<128
&& (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
&& sqlite3GlobalConfig.bUseCis && sqlite3GlobalConfig.bUseCis
&& OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan) && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan)
@@ -4594,9 +4593,9 @@ static int whereLoopAddBtree(
/* TUNING: Cost of a covering index scan is K*(N + log2(N)). /* TUNING: Cost of a covering index scan is K*(N + log2(N)).
** + The extra factor K of between 1.1 (iScanRatio between 0 ** + The extra factor K of between 1.1 (iScanRatio between 0
** and 9) and 2.8 (iScanRatio between 126 and 127) is added ** and 9) and 2.8 (iScanRatio between 126 and 127) is added
** to encourage the use of indexed lookups. ** to encourage the use of indexed lookups. FIXME
*/ */
pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + pProbe->iScanRatio/9 + 1; pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 10;
}else{ }else{
assert( b!=0 ); assert( b!=0 );
/* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N) /* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N)