News for hackers. Stuff that matters.
Re:I benchmarked nine Go SQLite drivers and here are the res... by jitl on Friday August 22, 2025 @12:02AM (#44980895)
For a project a while back, I needed to turn many-gigabyte Postgres CSV table dumps into SQLite databases. I turned to Go as its a great language for easy parallelism combined with enough memory layout control to get relatively good performance.

I quickly ruled out using database/sql drivers as the indirection through interface types added a bunch of overhead and stymied my attempts for reasonable memory layout. For my use-case, I found the crawshaw driver performed the best, but I ended up forking it as well as the Golang standard library CSV parser as I found defensive copying & allocation was the largest bottleneck. I ended up cycling several very large arenas among a CSV parser thread that filled the arena with column bytes and several threads writing to different temporary sqlite databases. Then at the end I ATTACHED them together and copied them into one big file (idk exactly why this is faster, but my profiles showed most cpu time spent in sqlite doing query binding things so MOAR CORES).

One notable optimization was exposing a way to bind borrowed bytes to query parameters without inducing a copy in either Golang caller code, or SQLite library code. The crawshaw driver upstream only exposes sqlite_bind_blob with SQLITE_TRANSIENT mode, which tells SQLite to copy the input to a private allocation before returning from the sqlite_bind* call. I added a version that passes SQLITE_STATIC, which means "trust me, I won't touch these bytes until the query is done, and I'll free them afterwards". This is safe in Rust who's "borrow" and "lifetime" concept models this perfectly, but I guess in Golang its dicey enough to not expose in your public package.

Here's the relevant commit in my fork: https://github.com/crawshaw/sqlite/commit/82ad4f03528e8fdc6a...

I'm curious how OP's https://github.com/cvilsmeier/sqinn would fare, I'm somewhat sus about copying 200GB to stdin but the benchmark results are pretty good so ¯\_(ツ)_/¯

Re:I benchmarked nine Go SQLite drivers and here are the res... by jitl on Friday August 22, 2025 @12:12AM (#44980928)
There may be an opportunity to switch from TRANSIENT to STATIC in sqinn but I didn't read deeply enough to follow what the current memory approach is. https://github.com/cvilsmeier/sqinn/blob/a88b3df6c89f0531e39...
Re:I benchmarked nine Go SQLite drivers and here are the res... by cvilsmeier on Saturday August 23, 2025 @10:26AM (#44996242)
According to my private tests, using STATIC instead of TRANSIENT does not yield a significant performance boost (maybe 1 to 5 percent, if at all).
Re:I benchmarked nine Go SQLite drivers and here are the res... by jitl on Saturday August 23, 2025 @01:03PM (#44997331)
I mean I love to see a 0.5% performance boost in my code at work. I would be all over a 5% boost, I think anything above 1% is significant!
Re:I benchmarked nine Go SQLite drivers and here are the res... by dav43 on Friday August 22, 2025 @02:55AM (#44981695)
Wouldn’t duckdb be a good fit for this?
Re:I benchmarked nine Go SQLite drivers and here are the res... by eknkc on Friday August 22, 2025 @04:04AM (#44982018)
I have done a lot of data migrations between sqlite -> postgres and such using duckdb. It works great but does not seem to perform well. I'd simply leave an instance churning data but a specialized small cli tool would probably work a lot faster.