SQLite

Check-in [e842ad391e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Updated comments. No code changes.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | auto-analyze
Files: files | file ages | folders
SHA1: e842ad391e62df273a5b1ed569d42ea46d03a99b
User & Date: drh 2017-02-18 22:52:40.654
Context
2017-02-20
13:11
Merge fixes from trunk. (check-in: ff213f2ef5 user: drh tags: auto-analyze)
2017-02-18
22:52
Updated comments. No code changes. (check-in: e842ad391e user: drh tags: auto-analyze)
15:58
Add the OP_SqlExec opcode and use it to implement "PRAGMA analyze_as_needed", invoking ANALYZE subcommands as necessary. This simplifies the implementation. (check-in: d386015f5e user: drh tags: auto-analyze)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/pragma.c.
1826
1827
1828
1829
1830
1831
1832

















1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850




1851


1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
  case PragTyp_SHRINK_MEMORY: {
    sqlite3_db_release_memory(db);
    break;
  }

  /*
  **  PRAGMA analyze_as_needed

















  */
  case PragTyp_ANALYZE_AS_NEEDED: {
    int iDbLast;
    int iTabCur;
    HashElem *k;
    Schema *pSchema;
    Table *pTab;
    Index *pIdx;
    LogEst szThreshold;
    char *zSubSql;

    iTabCur = pParse->nTab++;
    for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){
      if( iDb==1 ) continue;
      sqlite3CodeVerifySchema(pParse, iDb);
      pSchema = db->aDb[iDb].pSchema;
      for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
        pTab = (Table*)sqliteHashData(k);




        if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue;


        szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 );
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          if( !pIdx->hasStat1 ){
            szThreshold = 0;
            break;
          }
        }
        if( szThreshold ){
          sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
          sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, 
                            sqlite3VdbeCurrentAddr(v)+2, szThreshold);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|
|
|
|
|
|
|








>
>
>
>

>
>



|







1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
  case PragTyp_SHRINK_MEMORY: {
    sqlite3_db_release_memory(db);
    break;
  }

  /*
  **  PRAGMA analyze_as_needed
  **  PRAGMA schema.analyze_as_needed
  **
  ** This pragma runs ANALYZE on any tables which would have benefitted
  ** from having recent statistics at some point since the start of the
  ** current connection.  Only tables in "schema" are analyzed in the 
  ** second form.  In the first form, all tables except TEMP tables are
  ** checked.
  **
  ** A table is analyzed only if both of the following are true:
  **
  ** (1) The query planner used sqlite_stat1-style statistics for one or
  **     more indexes of the table at some point during the lifetime of
  **     the current connection.
  **
  ** (2) One or more indexes of the table are currently unanalyzed OR
  **     the number of rows in the table has increased by 25 times or more
  **     since the last time ANALYZE was run.
  */
  case PragTyp_ANALYZE_AS_NEEDED: {
    int iDbLast;           /* Loop termination point for the schema loop */
    int iTabCur;           /* Cursor for a table whose size needs checking */
    HashElem *k;           /* Loop over tables of a schema */
    Schema *pSchema;       /* The current schema */
    Table *pTab;           /* A table in the schema */
    Index *pIdx;           /* An index of the table */
    LogEst szThreshold;    /* Size threshold above which reanalysis is needd */
    char *zSubSql;         /* SQL statement for the OP_SqlExec opcode */

    iTabCur = pParse->nTab++;
    for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){
      if( iDb==1 ) continue;
      sqlite3CodeVerifySchema(pParse, iDb);
      pSchema = db->aDb[iDb].pSchema;
      for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
        pTab = (Table*)sqliteHashData(k);

        /* If table pTab has not been used in a way that would benefit from
        ** having analysis statistics during the current session, then skip it.
        ** This also has the effect of skipping virtual tables and views */
        if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue;

        /* Reanalyze if the table is 25 times larger than the last analysis */
        szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 );
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          if( !pIdx->hasStat1 ){
            szThreshold = 0; /* Always analyze if any index lacks statistics */
            break;
          }
        }
        if( szThreshold ){
          sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
          sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, 
                            sqlite3VdbeCurrentAddr(v)+2, szThreshold);