Strange choice of execution plan

I haven’t made any improvements lately on Phat. I mostly do this when I’m working on performance problems, I add a few new features here and there which come in handy right away. But I did not have to solve performance problems the last few months. Last week I found one problem which started as a little performance issue, but it turned out to be something completely else.

Complaints were that a batch was not performing well, and one thing led to another. Queries which were done were of the most simple form:

  • select <columns> from <table> where unique_id = <value>
  • delete from <table> where unique_id = <value>

Explain plan showed that a full table scan was performed while a unique index existed on the one column which was used as search predicate. Investigation on the size of table and index showed that an index should be used, reading a few block in an index and one block from the table was much more efficient than reading the entire 20+ MB table. So, just to make sure:

  • Index rebuild
  • Refrefh statistics

No change. Putting an index hint on the queries showed two strange things:

  • Cost was lower, why did the optimizer not choose for the index plan ?
  • Query used an ‘index full scan’, hello ? It’s a one column index, and were are not doing a count or so.

I decided to make a copy of the table in another schema, and I created a similar index on it. It gave the same behaviour, this did not give much clues. I tried a 10053 trace, despite the fact that I’m not very familiar with it yet. It showed all used variables which the optimizer used, and quite a short analysis of possible queries. It looked like it only calculated one plan, this was strange.

Next experiment I thought of got this problem in a different direction. I decided to export the table to my own test database. Running the export gave this error:

Connected to: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
Export done in AL32UTF8 character set and UTF8 NCHAR character set

About to export the entire database ...
. exporting tablespace definitions
. exporting profiles
. exporting user definitions
. exporting roles
. exporting resource costs
. exporting rollback segment definitions
. exporting database links
. exporting sequence numbers
. exporting directory aliases
. exporting context namespaces
. exporting foreign function library names
. exporting PUBLIC type synonyms
EXP-00008: ORACLE error 6552 encountered
ORA-06552: PL/SQL: Compilation unit analysis terminated
ORA-06553: PLS-553: character set name is not recognized
EXP-00000: Export terminated unsuccessfully

This looked strange, I checked out invalid objects immediatly. I found 1000+ invalid SYS objects. I tried to fix it:

  • utlrp.sql left dozens of invalid KU$ views
  • catalog.sql, catproc.sql, utlrp.sql still left them invalid
  • compiling an individual KU$ view gave ORA-06552, with a message like ‘type CHAR should be CHAR’
  • select on dba_registry showed that catalog was invalid

What has happened ? A ‘grep ORA-’ on the alert log showed the cause: a ‘CREATE DATABASE’ was done on this instance, the environment must have been set wrong when creating a new database. It has run on this existing database, and must have corrupted the catalog. Strange that a rerun of ‘catalog.sql’ did not fix the problem.

Anyway, a restore of the database was decided. After this the queries used the good old ‘index range scan’, and the exp worked again.

Leave a Reply