I'm considering to use SQLite database for a C# application which deals with large volumes of data series. The data is currently in several CSV files of up to 20GBs in size each and of the following format:
2019.07.31 00:00:03.855,1.11568,1.11571,3,0
I was expecting to reduce the size considerably when migrating to SQLite but to some reason am getting some different results.
The example string in CSV format takes 44 bytes (43 chars + new line). As far as I understood the SQLite types definitions described at sqlite.org it should take about the same in the database: 23 byte datetime text + 8*2 reals + 1*2 integers = 41 bytes
The dateTime can be stored as 8-byte integer (c# DateTime.Ticks) which should reduce the size to about 26 bytes per one line which is almost twice less than in CSV format.
For an experiment I tried importing 142,157 lines of data. The CSV file is about 6kk bytes in size but the resulting DB file is about 5kk which is almost the same. Compression (available in DB Browser for SQLite) does not change anything.
The table schema is:
CREATE TABLE "Data" ( "dateTime" INTEGER, "value1" REAL, "value2" REAL, "value3" INTEGER, "value4" INTEGER )
An example row looks like this:
637001280038550000 1.11568 1.11571 3 0
Is it the SQLite internals which make that big overhead in size? How can I reduce the size?
As a side note, setting Primary Key on the dateTime field reduces the size of the example data file by 0.3kk bytes but adding unique constraint increases it by 3kk bytes making it about 8kk in total which is much bigger than the CSV one.
Update
output from sqlite3_analyzer
w/t PK and contraints
Size of the file in bytes......................... 5242880
Bytes of user payload stored...................... 4349676 83.0%
Bytes of payload.................................. 4349852 83.0%
Bytes of metadata................................. 858115 16.4%
with PK
Size of the file in bytes......................... 4976640
Bytes of user payload stored...................... 3212420 64.5%
Bytes of payload.................................. 3212622 64.6%
Bytes of metadata................................. 1733838 34.8%
with PK and Unique constraint
Size of the file in bytes......................... 8134656
Bytes of user payload stored...................... 3212420 39.5%
Bytes of payload.................................. 3212622 64.6%
Bytes of metadata................................. 1733838 34.8%
*** Page counts for all tables and indices separately
TABLE............................................. 1214 61.1%
SQLITE_AUTOINDEX_TABLE_1.......................... 771 38.8%
So it turns out that the internals take 16%, PK takes additional 19% but still reduces the total size, and the unique contraint takes almost 40%!
The question remains valid. Is it possible to recude the size of the database or that is all one can get from it?
sqlite3_analyzer
program available on the sqlite website might be of interest to you.