Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I clear oracle execution plan cache for benchmarking?

Tags:

sql

oracle10g

People also ask

How do I clear the plan cache?

Use DBCC FREEPROCCACHE to clear the plan cache carefully. Clearing the procedure (plan) cache causes all plans to be evicted, and incoming query executions will compile a new plan, instead of reusing any previously cached plan.

What is query plan cache?

Every query requires a query plan before it is actually executed. This query plan is stored in SQL Server query plan cache. This way when that query is run again, SQL Server doesn't need to create another query plan; rather it uses the cached query plan which improved database performance.


Peter gave you the answer to the question you asked.

alter system flush shared_pool;

That is the statement you would use to "delete prepared statements from the cache".

(Prepared statements aren't the only objects flushed from the shared pool, the statement does more than that.)

As I indicated in my earlier comment (on your question), v$sql is not a table. It's a dynamic performance view, a convenient table-like representation of Oracle's internal memory structures. You only have SELECT privilege on the dynamic performance views, you can't delete rows from them.


flush the shared pool and buffer cache?

The following doesn't answer your question directly. Instead, it answers a fundamentally different (and maybe more important) question:

Should we normally flush the shared pool and/or the buffer cache to measure the performance of a query?

In short, the answer is no.

I think Tom Kyte addresses this pretty well:

http://www.oracle.com/technology/oramag/oracle/03-jul/o43asktom.html
http://www.oracle.com/technetwork/issue-archive/o43asktom-094944.html

<excerpt>

Actually, it is important that a tuning tool not do that. It is important to run the test, ignore the results, and then run it two or three times and average out those results. In the real world, the buffer cache will never be devoid of results. Never. When you tune, your goal is to reduce the logical I/O (LIO), because then the physical I/O (PIO) will take care of itself.

Consider this: Flushing the shared pool and buffer cache is even more artificial than not flushing them. Most people seem skeptical of this, I suspect, because it flies in the face of conventional wisdom. I'll show you how to do this, but not so you can use it for testing. Rather, I'll use it to demonstrate why it is an exercise in futility and totally artificial (and therefore leads to wrong assumptions). I've just started my PC, and I've run this query against a big table. I "flush" the buffer cache and run it again:

</excerpt>

I think Tom Kyte is exactly right. In terms of addressing the performance issue, I don't think that "clearing the oracle execution plan cache" is normally a step for reliable benchmarking.

Let's address the concern about performance.

You tell us that you've observed that the first execution of a query takes significantly longer (~28 seconds) compared to subsequent executions (~5 seconds), even when flushing (all of the index and data blocks from) the buffer cache.

To me, that suggests that the hard parse is doing some heavy lifting. It's either a lot of work, or its encountering a lot of waits. This can be investigated and tuned.

I'm wondering if perhaps statistics are non-existent, and the optimizer is spending a lot of time gathering statistics before it prepares a query plan. That's one of the first things I would check, that statistics are collected on all of the referenced tables, indexes and indexed columns.

If your query joins a large number of tables, the CBO may be considering a huge number of permutations for join order.

A discussion of Oracle tracing is beyond the scope of this answer, but it's the next step.

I'm thinking you are probably going to want to trace events 10053 and 10046.

Here's a link to an "event 10053" discussion by Tom Kyte you may find useful:

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:63445044804318


tangentially related anecdotal story re: hard parse performance

A few years back, I did see one query that had elapsed times in terms of MINUTES on first execution, subsequent executions in terms of seconds. What we found was that vast majority of the time for the first execution time was spent on the hard parse.

This problem query was written by a CrystalReports developer who innocently (naively?) joined two humongous reporting views.

One of the views was a join of 62 tables, the other view was a join of 42 tables.

The query used Cost Based Optimizer. Tracing revealed that it wasn't wait time, it was all CPU time spent evaluating possible join paths.

Each of the vendor supplied "reporting" views wasn't too bad by itself, but when two of them were joined, it was agonizingly slow. I believe the problem was the vast number of join permutations that the optimizer was considering. There is an instance parameter that limits the number of permutations considered by the optimizer, but our fix was to re-write the query. The improved query only joined the dozen or so tables that were actually needed by the query.

(The initial immediate short-term "band aid" fix was to schedule a run of the query earlier in the morning, before report generation task ran. That made the report generation "faster", because the report generation run made use of the already prepared statement in the shared pool, avoiding the hard parse.

The band aid fix wasn't a real solution, it just moved the problem to a preliminary execution of the query, when the long execution time wasn't noticed.

Our next step would have probably been to implement a "stored outline" for the query, to get a stable query plan.

Of course, statement reuse (avoiding the hard parse, using bind variables) is the normative pattern in Oracle. It mproves performance, scalability, yada, yada, yada.

This anecdotal incident may be entirely different than the problem you are observing.


HTH


It's been a while since I worked with Oracle, but I believe execution plans are cached in the shared pool. Try this:

alter system flush shared_pool;

The buffer cache is where Oracle stores recently used data in order to minimize disk io.


We've been doing a lot of work lately with performance tuning queries, and one culprit for inconsistent query performance is the file system cache that Oracle is sitting on.

It's possible that while you're flushing the Oracle cache the file system still has the data your query is asking for meaning that the query will still return fast.

Unfortunately I don't know how to clear the file system cache - I just use a very helpful script from our very helpful sysadmins.