> Depending on what you are storing in fs_textid and what your LIKE  
> pattern is, you might get much better performance (and lower memory  
> usage) if you use GLOB instead of LIKE and if you explicitly code the  
> pattern rather than using the wildcard "?", and if you create a new  
> index:
> CREATE INDEX newidx1 ON fs_main(fs_itemtype, fs_textid);
Thank you for the optimization hints – I changed the application that it uses 
all three suggestions and many queries 
are now executed faster. Although, not if the search string begins with a 
wildcard char-acter as described in http:
//www.sqlite.org/optoverview.html#like_opt under point 2. I assume this causes 
again most of the  database to be loaded 
into cache as this was the case with the LIKE opera-tor.

> Are you sure that the memory is not freed?  Calling free() does not  
> normally return memory to the operating system so just because the  
> process memory usage went up does *not* mean that the memory is still  
> in use. It might just mean that the memory is being held by the  
> malloc()/free() for possible reuse later.  What does the  
> sqlite3_memory_used() interface tell you?  What about  
> sqlite3_memory_highwater()?
I wrote two small example programs to illustrate the memory usage difference 
between working on the main database and 
working with multiple ATTACHed database. The example with just one main 
database does not consume more than ~300KB 
which seems to be pretty close to the specified 'cache_size'. The second 
example with three attached database consumes 
around 500KB per query and it looks like 'cache_size' setting is not relevant. 
All memory seems to be freed correctly.

--- Example A ---
--- One database only, cache size limited to 250 pages ---

    long rc = SQLITE_OK;

    sqlite3_int64 mem01;
    sqlite3_int64 mem02;

    // Open database connection
    sqlite3* m_pDB;
    sqlite3_open("job01.db", &m_pDB);   // application memory usage: 1.5 MB

    // PRAGMA
    sqlite3_stmt* pStmtPragma01(NULL);
    rc = sqlite3_prepare_v2(m_pDB, "PRAGMA cache_size=250", -1, &pStmtPragma01, 
NULL);
    rc = sqlite3_step(pStmtPragma01);                                           
              
    rc = sqlite3_finalize(pStmtPragma01);

    // Run queries
    sqlite3_stmt* pStmtLike01(NULL);
    rc = sqlite3_prepare_v2(m_pDB, "SELECT COUNT(fs_recid) FROM main.fs_main 
WHERE fs_itemtype=10 AND fs_textid GLOB 
'*1';", -1, &pStmtLike01, NULL);
    mem01 = sqlite3_memory_used();          // 17937   ...application memory 
usage: 1.8MB
    rc = sqlite3_step(pStmtLike01);  
    mem01 = sqlite3_memory_used();          // 305725  ...application memory 
usage: 2.0MB
    rc = sqlite3_finalize(pStmtLike01);
    mem01 = sqlite3_memory_used();          // 302855  ...application memory 
usage: 2.0MB
    mem02 = sqlite3_memory_highwater(1);    // 305757

    // Close database connection
    sqlite3_close(m_pDB);   // application memory usage: 1.5 MB <- all memory 
is freed correctly




--- Example B ---
--- :memory: database and three attached databases, cache size limited to 250 
pages ---

    long rc = SQLITE_OK;

    sqlite3_int64 mem01;
    sqlite3_int64 mem02;

    // Open database connection
    sqlite3* m_pDB;
    sqlite3_open(":memory:", &m_pDB);   // application memory usage: 1.5 MB

    // PRAGMA
    sqlite3_stmt* pStmtPragma01(NULL);
    rc = sqlite3_prepare_v2(m_pDB, "PRAGMA cache_size=250", -1, &pStmtPragma01, 
NULL);        
    rc = sqlite3_step(pStmtPragma01);                                           
              
    rc = sqlite3_finalize(pStmtPragma01);

    // ATTACH job databases
    sqlite3_stmt* pStmtAttach01(NULL);
    rc = sqlite3_prepare_v2(m_pDB, "ATTACH 'job01.db' AS _job01;", -1, 
&pStmtAttach01, NULL); 
    rc = sqlite3_step(pStmtAttach01);                                           
              
    rc = sqlite3_finalize(pStmtAttach01);                                       
              
    sqlite3_stmt* pStmtAttach02(NULL);
    rc = sqlite3_prepare_v2(m_pDB, "ATTACH 'job02.db' AS _job02;", -1, 
&pStmtAttach02, NULL); 
    rc = sqlite3_step(pStmtAttach02);                                           
               
    rc = sqlite3_finalize(pStmtAttach02);                                       
              
    sqlite3_stmt* pStmtAttach03(NULL);
    rc = sqlite3_prepare_v2(m_pDB, "ATTACH 'job03.db' AS _job03;", -1, 
&pStmtAttach03, NULL); 
    rc = sqlite3_step(pStmtAttach03);                                           
               
    rc = sqlite3_finalize(pStmtAttach03);                                       
              

    // Run queries
    sqlite3_stmt* pStmtLike01(NULL);
    rc = sqlite3_prepare_v2(m_pDB, "SELECT COUNT(fs_recid) FROM _job01.fs_main 
WHERE fs_itemtype=10 AND fs_textid 
GLOB '*1';", -1, &pStmtLike01, NULL);
    mem01 = sqlite3_memory_used();          // 42568   ...application memory 
usage: 1.8MB
    rc = sqlite3_step(pStmtLike01);  
    mem01 = sqlite3_memory_used();          // 526932  ...application memory 
usage: 2.3MB
    rc = sqlite3_finalize(pStmtLike01);
    mem01 = sqlite3_memory_used();          // 524058  ...application memory 
usage: 2.3MB
    mem02 = sqlite3_memory_highwater(1);    // 526964

    sqlite3_stmt* pStmtLike02(NULL);
    rc = sqlite3_prepare_v2(m_pDB, "SELECT COUNT(fs_recid) FROM _job02.fs_main 
WHERE fs_itemtype=10 AND fs_textid 
GLOB '*1';", -1, &pStmtLike02, NULL);
    mem01 = sqlite3_memory_used();          // 526656 ...application memory 
usage: 2.3MB
    rc = sqlite3_step(pStmtLike02);             
    mem01 = sqlite3_memory_used();          // 965624 ...application memory 
usage: 2.8MB
    rc = sqlite3_finalize(pStmtLike02);
    mem01 = sqlite3_memory_used();          // 965624 ...application memory 
usage: 2.8MB
    mem02 = sqlite3_memory_highwater(1);    // 965656

    sqlite3_stmt* pStmtLike03(NULL);
    rc = sqlite3_prepare_v2(m_pDB, "SELECT COUNT(fs_recid) FROM _job03.fs_main 
WHERE fs_itemtype=10 AND fs_textid 
GLOB '*1';", -1, &pStmtLike03, NULL);
    mem01 = sqlite3_memory_used();          // 965348  ...application memory 
usage: 2.8MB
    rc = sqlite3_step(pStmtLike03);  
    mem01 = sqlite3_memory_used();          // 1285588 ...application memory 
usage: 3.1MB
    rc = sqlite3_finalize(pStmtLike03);
    mem01 = sqlite3_memory_used();          // 1282714 ...application memory 
usage: 3.1MB
    mem02 = sqlite3_memory_highwater(1);    // 1285620

    // Close database connection
    sqlite3_close(m_pDB);   // application memory usage: 1.5 MB <- all memory 
is freed correctly


Questions:
- > Is there one cache per database connection or one cache per ATTACH'ed 
database?
- Is it true, that 'cache_size' does not limit the total memory used by SQLite 
correctly when ATTACH is used?
- How can I limit the total amount of memory that is used by SQLite event if I 
work with ATTACH?



Regards
Daniel


_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to