mi

Extension for sqlite that provides transparent dictionary-based row-level compression for sqlite. This basically allows you to compress entries in a sqlite database almost as well as if you were compressing the whole DB file, but while retaining random access.

Depending on the data, this can reduce the size of the database by 90% while keeping performance mostly the same.

Transparent Compression

Basic Functionality

Installation

You can either load this library as SQLite extension or as a Rust library. Note that sqlite extensions are not persistent, so you need to load it each time you connect to the database.

Sqlite CLI

Either load it in the REPL:

sh $ sqlite3 file.db SQLite version 3.34.0 2020-12-01 16:14:00 sqlite> .load .../libmi.so [2020-12-23T21:30:02Z INFO mi::create_extension] [mi] initialized sqlite>

Or alternatively:

sqlite3 -cmd '.load libmi.so'

C Api

c int success = sqlite3_load_extension(db, "libmi.so", NULL, NULL);

See here for more information.

Rust

The recommended method is to add mi as a dependency to your project, then load it using

rust let conn: rusqlite::Connection; mi::load(&conn)?;

Alternatively, you can load the extension like any other extension:

rust let conn: rusqlite::Connection; conn.load_extension("libmi.so", None)?;

See here for more information.

Verbosity / Debugging

You can change the log level by setting the environment variable RUST_LOG=mi=error for less logging and RUST_LOG=mi=debug for more logging.

Future Work / Ideas / Todo

TODO: describe

select zstdenabletransparent('{"table": "events", "column": "data", "compressionlevel": 19, "dictchooser": "case when date(timestamp, ''weekday 0'') < date(''now'', ''weekday 0'') then data_type || ''.'' || date(timestamp, ''weekday 0'') else null end"}');

select case when date(timestamp, 'weekday 0') < date('now', 'weekday 0') then data_type || '.' || date(timestamp, 'weekday 0') else null END from events limit 10000