> 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
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users