Hello,

I'm having a big performance problem while trying to use sqlite as a
data output for my application. The application writes out a bunch of
packets relatively fast. There are about 10 different types of them
with all but one sizing under 100 bytes. Those small ones I write out
roughly once per second or less. The big one is the "real" data that
gets logged from ~10-1000x per second. It's size can be from 2-3kb to
32kb and it's size depends on other parameters that don't change very
often, generally not more than every few minutes. Raw data output rate
is at most ~8MiB/s and generally is around 3-5. At the time of writing
the files are never altered, just a bunch of data gets added to them
up to around 1GB is reached, then a new file is created.

When using my current flat-file output it doesn't cause almost any
measurable system load. When using the DB it pretty much halts the
application without causing significant CPU load. The data still gets
logged to DB but at a fraction of the speed it should be (~1MB per 15s
vs 5MB/s). I'm quite new to sqlite so I'm not really sure how to
benchmark it or how to know what is causing the slowdown. So far it
seems if I disable saving the big packets it works perfectly. The
overhead of using SQLite is needed to be absolutely minimal as the
application itself is doing a whole lot of raw computations already.
Flat file output has almost zero overhead but any modifications to
file format make things quite a bit complicated.

The big packet table is created like this:

    char *errMsg = 0;
    sqlite3_exec(db,
                "CREATE TABLE Data (                    \
        NumRows         INTEGER NOT NULL,   \
        NumColumns      INTEGER NOT NULL,   \
        RowSize         FLOAT NOT NULL,     \
        Begin                   FLOAT NOT NULL,     \
        End                     FLOAT NOT NULL,     \
        DataBegin       FLOAT NOT NULL,     \
        DataEnd         FLOAT NOT NULL,     \
        Timestamp       DOUBLE NOT NULL,    \
        PacketID        INTEGER NOT NULL,   \
        Data                    BLOB NOT NUlL,          \
        ID              INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL)",
        0,
        0,
        &errMsg);


Data is inserted with this piece of code:

    DataPing* ping = packet.dataPing;
    const string queryStr = "INSERT INTO DataPing (NumRows,
NumColumns, Begin, End, DataBegin, DataEnd, Timestamp, PacketID,
Data)"
        "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
    sqlite3_stmt* query(NULL);
    long rc = SQLITE_OK;


    if (query == 0) {
        rc = sqlite3_prepare_v2(db, queryStr.c_str(), queryStr.size(),
&query, NULL);
            if (rc != SQLITE_OK) {
                TRACE_PRINT("error", ("SQL error: %s", sqlite3_errmsg(db)))
            }
        }


    sqlite3_bind_int(           query, 1, ping->numRows);
    sqlite3_bind_double(        query, 2, ping->numColumns);
    sqlite3_bind_double(        query, 3, ping->begin);
    sqlite3_bind_double(        query, 4, ping->end);
    sqlite3_bind_int(           query, 5, ping->dataBegin);
    sqlite3_bind_double(        query, 6, packet.dataEnd);
    sqlite3_bind_int(           query, 7, packet.timestamp);
    sqlite3_bind_int(           query, 8, packet.packetId);
    sqlite3_bind_blob(          query, 9, &ping->data[0],
ping->numRows*ping->numColumns*sizeof(ping->data[0]), 0);
    if (rc != SQLITE_OK) {
        TRACE_PRINT("error", ("SQL error: %s", sqlite3_errmsg(db)))
    }
    rc = sqlite3_step(query);
    if (rc != SQLITE_OK && rc!=SQLITE_DONE) {
        TRACE_PRINT("error", ("SQL error: %d: %s", rc, sqlite3_errmsg(db)))
    }
    rc = sqlite3_reset(query);

        
Basic data flow is program receives packet -> packet is parsed ->
packet is logged -> data from packet is used in a lot of computations
-> packet is destroyed (memory freed)


I have no idea how to fine-tune sqlite behavior, if I'm doing the
querys correctly or if I'm doing something else wrong. I tried to use
transactions by doing a pair of end/begin queries once per second but
it didn't seem to change much. Data got saved just fine but it was
still horribly slow. My best guess at the moment is that program hangs
because of excessive file synchronization. Anyone has any better
guesses what could be the problem and how to solve them?

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

Reply via email to