Many of you probably know Martin Bach.  He’s a colleague here at Oracle although we’ve both been good mates in the Oracle community long before either of us joined Oracle.

But here’s the issue. Martin is just a genuinely nice guy and always takes an optimistic glass-half-full view to the world.

So recently when he posted a cautionary tale about bind variables and their impact on performance, he concluded up the post with some results from a simple benchmark showing that not using bind variables could incur a 5x performance hit on your system (let alone the other memory and concurrency implications).

Here’s my theory: There’s the SQL injection risk and there’s the performance impact…but because Martin’s a good guy, he didn’t want to terrify you as a developer if you were reading blog and suddenly realised you were not using bind variables in your code.

But I’m not Martin 🙂 I’m a bitter twisted dude that comes from an island where the world used to send its convicts. No rose coloured glasses from this neck of the woods. We call it like it is!

output

Let me show just how bad things can get if you do not listen to Martin’s advice.

I’ll start with a simple demo where I’ll do 10,000 individual primary key lookups to a simple table. This little Java program creates and populates a table, and then builds its SQL query with concatenation of literals (and hence no bind variable use).

image

I run the program against my local database and got this:

$ java ParseDemo
Creating test table
Done
Querying table with individual values
10,000 iterations, 4665 ms

Throughput 2143/sec

and with thanks to the magic of modern computer hardware, we get over 2000 executions per second, which will make many a developer feel: “Well, that’s probably good enough”

Just like Martin did, I now swap in some code to replace the literal SQL queries with a bind variable version

image

and in my case, I got a 10x improvement

$ java ParseDemoBind
Creating test table
Done
Querying table with bind values
10,000 iterations, 407 ms

Throughput 24570/sec

At which point you’re probably thinking: “You have just replicated Martin’s findings. What is the big deal?”

But database applications are not simple things. We often do simple demos to illustrate a point, but when was the last time you saw a modern application just doing primary key lookups? They have views, and security predicates, and complex joins and all sorts of things that are needed for genuine enterprise level applications.

So let me swap in this new version of the code

image

What happens when the SQL statement you need to parse is a “serious” one? Lets take a look at the results

$ java ParseDemo2 20
Querying table with individual values
2138 ms

Throughput 9/sec

Welcome to parsing purgatory. And if you’re thinking that maybe we just need more “ramp up”, you can see that this does not help at all

$ java ParseDemo2 400
Querying table with individual values
39531 ms
Throughput 10/sec

10 queries per second! Can you imagine fronting up to your CEO and saying “Yeah, we only get 10 queries per second because I didn’t want to add a couple of extra lines of code to my Java app

Let’s compare that to the bind variable equivalent

image

$ java ParseDemo2Bind 40000
Querying table with bind values
1940 ms

Throughput 20618/sec

You’re seeing that correctly – this is a 2000x performance jump!

I cannot stress this highly enough – All of that (excellent!) demo code out there on the interwebs proving that bind variables are 5x or 10x better than not using them were dramatically underselling the impact.  I’m not criticising them for that – it is important to post simple, easy to reproduce examples in demos in order to keep things as simple as possible for readers to digest. That is how efficient learning is done.  However, once people started thinking: “Hey, I’ll still get 2000 queries per second even without binds” then I decided it was time to set the record straight.

Do you want 10 queries per second or 20,000 per second?

3 responses to “Bind Variables – Worse than you were told”

  1. Would be great to also demo the impact on concurrency…

    1. Will try find a machine with plenty of cores to test this out. (We all know the result won’t be good :-))

  2. peanutquickly3ad424adaa Avatar
    peanutquickly3ad424adaa

    Great demo Connor, the “parsing purgatory” example really illustrates the impact.

    I’ve seen cases where developers assume that things like session cursor caching or JDBC statement caching will help even when SQL is built with literal concatenation. But once the SQL text changes every execution, those layers can’t really help and the database ends up hard parsing everything.

    That’s when systems suddenly fall off a performance cliff… and somehow it becomes the DBA’s fault 😄.

    Regards,
    jorge

Leave a Reply

Trending

Discover more from Learning is not a spectator sport

Subscribe now to keep reading and get access to the full archive.

Continue reading