How to find if your SQL is using SPM baseline
I’ve always wondered how many of my SQLs are NOT using baselines.
Of course, when you run DBMS_XPLAN.DISPLAY_CURSOR for the statement, it can put a nicely formatted note for you, something like:
-----
- SQL plan baseline "SQL_PLAN_01yu884fpund494ecae5c" used FOR this statement
But can you find it globally for ALL SQLs in the shared pool ?
How to add a hint to ORACLE query without touching its text
If you’ve been a DBA long enough, you’ve probably seen multiple cases where certain SQL queries just refuse to cooperate.
I.e. you KNOW that the query is supposed to use index IDX1, but ORACLE stubbornly decides to take IDX2. Rats!
The usual suspect here is bad statistics and thus the usual advise is: start re-collecting them. But while this might help, the success is far from guaranteed! Moreover, with a ‘real production’ data statistics collection could take hours (days?) and you already have people screaming about slow performance … In other words, you need to fix the problem NOW and waiting until stats collection maybe fixes the problem a few hours down the road is just not an option!
Smile: I don’t always drink beer …
Remember the ever annoying (but hilarious) Dos Equis guy commercials about “the most interesting man in the world…” ?
Well, I’ve heard a good one today:
… I don’t always test my software … but when I do, I test it in PROD !
Thanks, Arup. Stay thirsty my friends
How to find SPM baseline by sql_id
When you start working with SQL Plan baselines, one of the annoying things that you might find is that the main “baseline” dictionary view dba_sql_plan_baselines does not have sql_id column.
How to freeze ORACLE database by strace
Sometimes when you trace things, you can discover some really interesting (and unexpected) stuff.
For example, here is a simple way to “freeze” your ORACLE database, which I “discovered” while tracing system calls in LGWR process (ORACLE 11.2.0.2 on Linux 2.6.18 ×64).
ora_cpu.pl tool for Linux
A very brief update.
One of the smaller (and nicer) part of ORA_MEM package is ora_cpu.pl utility that shows graphically what active db processes are doing at the moment … be it running SQL, accessing db object or waiting for something.
As an added benefit, it also shows some important OS statistics, such as process state or ‘spot’ CPU utilization for your database sessions.
How to become regular ORACLE user when you do NOT know the password
This is a fairly common situation for a DBA: you can always connect as SYSDBA, but sometimes you really need to connect as a regular database user (i.e. to have proper environment for your queries).
If you are root in UNIX, this would be extremely easy to do:
Unfortunately, ORACLE does not have an equivalent su command and, even if you are SYS, to connect to any regular database user you need to know its password (which could be a problem).
Still, there is a simple workaround that can be applied here. Essentially, you can save user’s old password, change it to some dummy value and quickly change it back after your connection is established.
While user password hashes are no longer exposed in DBA_USERS view (starting with 11g, I believe), they are still available in SYS.USER$.
Below is the script that does exactly that (full credit goes to Matt Parker who showed me this trick).
COLUMN user_pwd new_value SZ_PWD
SET termout off
SELECT password AS user_pwd FROM USER$ WHERE UPPER(name)='&BECOME_USER';
spool '/tmp/.&BECOME_USER..CHANGE'
prompt SET termout off
prompt CONNECT / AS sysdba
prompt ALTER USER &BECOME_USER IDENTIFIED BY VALUES '&SZ_PWD';;
prompt exit
spool off
ALTER USER &BECOME_USER IDENTIFIED BY TEMPORARY;
CONNECT &BECOME_USER/TEMPORARY
host sqlplus -S /nolog @/tmp/.&BECOME_USER..CHANGE
host rm /tmp/.&BECOME_USER..CHANGE
SET termout ON
SHOW USER
undef BECOME_USER
The troubling global nature of SQL Profiles and SPM Baselines
Did you know that SQL profiles and SPM baselines collected for SQL statements in one schema can apply to “the same” SQL statements in another schema ?
They do ! And, besides, objects that these SQLs apply to do NOT need to be exactly the same … And I’m not just talking about different data values or different number of records … The objects can have different structure! Or, they can actually be of different type, i.e. views instead of tables …
The only things that matter are: SQL text and object names.
This strange behavior is summarized in the table below:
| BEHAVIOR | SQL Profile | SPM Baseline |
|---|---|---|
| “Fire” for object in a different schema | YES | YES |
| “Fire” for object with a different DATA | YES | YES |
| “Fire” for object with a different STRUCTURE | YES | YES |
| “Fire” when indexes are different | YES | MAYBE, will “fire” if the same execution plan is still produced |
| “Fire” when indexes are missing | YES | NO |
| “Fire” when TABLE is replaced by VIEW | YES | NO |
| “Fire” when TABLE is replaced by MVIEW | YES | NO |
And, if you do not believe me, read on …
What is the difference between SQL Profile and SPM Baseline ?
-----
- SQL profile "SYS_SQLPROF_012ad8267d9c0000" used FOR this statement
and SPM Baselines
-----
- SQL plan baseline "SQL_PLAN_01yu884fpund494ecae5c" used FOR this statement
are both relatively new features of ORACLE Optimizer with Profiles first appearing in version 10 and SPM Baselines in version 11.
Both SQL Profiles and SPM Baselines are designed to deal with the same problem: Optimizer may sometimes produce a very inefficient execution plan, and they are both doing it by essentially abandoning the idea that “all SQLs are created equal”. Instead, another idea is put forward: “Some SQLs are special and deserve individual treatment”.
What are SQL Profiles and why do we need them ?
If you use DBMS_XPLAN package to analyze execution plans for your SQL statements (and you really should these days), you might have noticed that at times the following line might be displayed along with your execution plan:
-----
- SQL profile "SYS_SQLPROF_012ad8267d9c0000" used FOR this statement
This seems to mean that:
- An external ‘helper’ object was used during evaluation of your SQL statement
- This ‘helper’ object changed (or, at least, influenced) its execution plan
While having some extra help is nice, one has to wonder: what exactly is this “profile” object ? What does it do ? And, in a bigger picture, why do we need “external” help evaluating SQL statements at all ?