How much of a performance difference have y'all seen by switching from java.jdbc to next.jdbc? I couldn't find published benchmarks anywhere. I tried benchmarking a couple spots in my application with one vs the other and didn't really notice a difference
It'll depend on a number of things.
If you use plan in next.jdbc, you can avoid building Clojure data structures from ResultSet objects and that can be a big saving. The larger the ResultSet, the larger that saving will be.
Overall, there is a saving from working with native Java objects in next.jdbc (`Connection`, DataSource, etc and protocols) compared to java.jdbc (which uses a hash map and conditional logic to handle the same behavioral selection).
Can you be a bit more specific about what you're doing and exactly what code you are comparing across the two libraries?
Oh, so it sounds like I need to do more than just swapping out calls to clojure.java.jdbc/query with calls to next.jdbc/execute if I want to see noticeable performance benefits, is that right?
I only tested with a couple of my slower queries (they're slow because of the number of results they return, and not because of a lack of indices or anything like that). One of them returns 130k records. A quick "clojure-goes-fast" flamegraph shows that a lot of time is spent converting the JSONB results to clojure objects, but even after controlling for that, I didn't see any speed up that warranted further evaluation for refactoring the entire application to use next.jdbc. So I assumed I was potentially missing something
Are you using plan
That's where the savings will be
next.jdbc itself does not convert JSONB to Clojure data so you'll also want to look at how/where that conversion is actually happening
Fwiw, here’s my experience https://github.com/cljdoc/cljdoc/issues/771#issuecomment-1595487296
I'm not using plan yet, so I'll give that a shot next time I get the chance.
Regarding json / jsonb parsing, I set things up in accordance with what I found in the tips&tricks section. So the JSON parsing is happening
Yes, but to be clear, that's not next.jdbc, that's you extending it to do the JSON parsing -- so if the bottleneck is JSON conversion, that's down to whatever library you're using for that. next.jdbc itself does not do JSON conversion.
Yep, I get that. I think we're saying the same thing. As I mentioned above, I controlled for the performance penalty of parsing the JSON values by ensuring that both JDBC setups were parsing results using the same library.
I've also toyed with the idea of just wrapping the jsonb results in delay so that I only incur the JSON parsing penalty if I actually plan to use the value
When I get the chance to revisit this, I'll use plan and test out a scenario that doesn't involve JSON parsing altogether
1. Too often, people store huge JSON blobs and then select them entirely although in fact, they need a couple of fields. If it's your case, select only those fields you really need, for example:
select id, created_at, data->>'foo' as foo, data->'user'->>'email' as email from my_table
2) you say, you select 130 rows. But for what? Are you going to send them via HTTP or write to a file? You barely need to have 130k of rows in memory. Use plan, as was said above, to reduce rows one by one as they come from the newtork.
3) If it's Postrgres, try COPY ... TO command that dumps a table or a query into an OutputStream. The stream might be bound to a file, or it might be Gzipped in-memory ByteArrayOutputStream