Question

This question may be better suited for the DB stackexchange site, but I wasn't sure.

Anyway, I'm dealing with optimizing queries, and I learned that using bind variables makes the parser not work as hard. We have seen improvements in the queries being run, but I'm wondering if subbing out the static variables being passed in by our software for bind variables as well will help. Here's an example:

select *
from report
where report.name = :1
and report.enabled = '1'

I could sub that out to say

select *
from report
where report.name = :1
and report.enabled = :2

I would just make the change, but the process of actually doing it in the software and seeing the difference it makes is somewhat long and tedious. Does anyone know if mixing literals (as in the first example) hurts the optimizer efficiency even though they are constantly the same?

Thanks in advance.

Was it helpful?

Solution

I'm not exactly sure what you mean by I learned that using bind variables makes the parser not work as hard, but I'll guess...


Are you building the SQL strings in your client and sending them to the oracle database to execute?

If so, the act of parametrising the queries means that the DB engine can see that several queries, although with different parameters, can be met using the same execution plan / explain plan.

This means that the engine does not need to re-compile the native SQL, and can re-use a plan already (potentially) in the cache.

Without parametrisation, and with different values for "name", the engine would see the queries as totally different and not notice the similarity. That would cause the SQL to be compiled unless the exact same string is already in the cache.


If your queries, however, always have report.enabled = 1, there is no need to parametrise that part of the query. As it is static, the act of not using a parameter won't make it look like a different query, and won't cause it to be re-compiled.

On the contrary, you may actually make savings depending on indexes, the statistics of your data, etc. If, for example, 99% of you data is "enabled = 1" you may get a different plan compared to 1% of your data being "enabled = 1". But the engine will only optimise for "enabled = 1" in a query where it is known that the value being looked for is always 1. And that's only the case when it's specified statically (as a literal).


In short, if it's truly a static value, don't parametrise it.

OTHER TIPS

If your SQL really contains constants (ie the clause is always enabled=1), I see several reasons for letting them as literals in your SQL:

  • It is easier to debug when you have a performance problem and not immediate access to the value of the binds (in some trace files for example)
  • The optimizer can sometimes estimate the cardinality of a query more efficiently when using constants (ie: when bind peeking is disabled or for older versions of the DBMS), especially if you have statistics with histograms on this column
  • You need to use constants for some specific plan option (partition pruning for example)

Also, beside performance, the other main reason to use parametrized queries is to prevent SQL injection. True constants wouldn't be subject to SQL injection since they would be provided by your code and not by an outside source.

The answer, as it frequently is, is "it depends."

On what? Is your application OLTP (many queries, small result sets) or DSS (few queries, lots of data)? What's the skew involved in the columns you're looking at changing from binds to literals? Do those columns need to be bindable, or are they always bound to the same values?

When Oracle receives a SQL statement, it first looks if the SQL statement and its execution plan already exists in the cache. If it does, it saves the cost of recreating the execution plan, thus saving execution time. In order for an incoming SQl statement to match one in the cache, it has to be an exact match (including leterals, bind variables and white spaces). Thats why it is encouraged to use bind variables so that the satement remains the same for different values (and hence different literals) of the variable. But if the same literal is being used all the time, there is no difference with using bind varialbes. The performance will be same in both cases in terms of parsing and execution plan generation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top