sql

stephenmhopper 2024-06-01T19:47:30.009589Z

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

seancorfield 2024-06-01T19:58:04.243789Z

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?

stephenmhopper 2024-06-01T20:04:29.823749Z

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?

stephenmhopper 2024-06-01T20:06:20.882099Z

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

seancorfield 2024-06-01T20:37:09.926269Z

Are you using plan

seancorfield 2024-06-01T20:37:17.615759Z

That's where the savings will be

seancorfield 2024-06-01T20:39:35.426089Z

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

lread 2024-06-01T21:18:11.723449Z

Fwiw, here’s my experience https://github.com/cljdoc/cljdoc/issues/771#issuecomment-1595487296

👍 1
stephenmhopper 2024-06-02T03:34:38.421909Z

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

seancorfield 2024-06-02T06:24:48.733689Z

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.

stephenmhopper 2024-06-02T11:53:26.504329Z

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

igrishaev 2024-06-02T17:22:34.085149Z

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