From 02ce7ec581e490449391d2d17087ec41d169b0a4 Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Sat, 26 Dec 2020 22:05:20 +0800 Subject: [PATCH] Add ?_cache_size=[..] to connection parameters (#894) Add a shortcut for PRAGMA cache_size; this is a pretty useful setting: the default of -2000 (2M) is not especially high, and a lot of people will probably want to increase this. For example, while running a bunch of fairy expensive queries in parallel: With SetMaxOpenConns(1): -2000: 5762ms -20000: 4714ms With SetMaxOpenConns(20): -2000: 3067ms -20000: 2532ms Which isn't a bad performance boost for changing a single number. --- README.md | 2 ++ sqlite3.go | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/README.md b/README.md index c4149c0..746621f 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,8 @@ Boolean values can be one of: | Time Zone Location | `_loc` | auto | Specify location of time format. | | Transaction Lock | `_txlock` | | Specify locking behavior for transactions. | | Writable Schema | `_writable_schema` | `Boolean` | When this pragma is on, the SQLITE_MASTER tables in which database can be changed using ordinary UPDATE, INSERT, and DELETE statements. Warning: misuse of this pragma can easily result in a corrupt database file. | +| Cache Size | `_cache_size` | `int` | Maximum cache size; default is 2000K (2M). See [PRAGMA cache_size](https://sqlite.org/pragma.html#pragma_cache_size) | + ## DSN Examples diff --git a/sqlite3.go b/sqlite3.go index a66c7f7..d1ff406 100644 --- a/sqlite3.go +++ b/sqlite3.go @@ -1040,6 +1040,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { synchronousMode := "NORMAL" writableSchema := -1 vfsName := "" + var cacheSize *int64 pos := strings.IndexRune(dsn, '?') if pos >= 1 { @@ -1363,6 +1364,18 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { } } + // Cache size (_cache_size) + // + // https://sqlite.org/pragma.html#pragma_cache_size + // + if val := params.Get("_cache_size"); val != "" { + iv, err := strconv.ParseInt(val, 10, 64) + if err != nil { + return nil, fmt.Errorf("Invalid _cache_size: %v: %v", val, err) + } + cacheSize = &iv + } + if val := params.Get("vfs"); val != "" { vfsName = val } @@ -1675,6 +1688,14 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { } } + // Cache Size + if cacheSize != nil { + if err := exec(fmt.Sprintf("PRAGMA cache_size = %d;", *cacheSize)); err != nil { + C.sqlite3_close_v2(db) + return nil, err + } + } + if len(d.Extensions) > 0 { if err := conn.loadExtensions(d.Extensions); err != nil { conn.Close()