I love to learn something new every day. And on Friday afternoon last week I learned something new again. It started (as often) with a very simple question from a colleague working from the Oracle Malaga office in Spain. The customer has an issues with some queries being slower than before once they moved from on-prem to the cloud into a PDB. But are queries on dictionary tables are slow in Oracle Multitenant generally?

Photo by Pascal van de Vendel on Unsplash
What was the case?
The customer ran some queries against dictionary views in the PDB in Oracle Database 19c. But the timing in their cloud environment was much worse by factors to the timings they could measure in their own on-premise environment. Then the customer altered the query from accessing ALL_-views originally now to DBA_-views instead. Interestingly enough, the performance was good again. So, it had obviously nothing to do with on-prem vs cloud.
This is the original query the customer ran:
select * from
(select null table_qualifier, o1.owner table_owner, o1.object_name table_name, decode(o1.owner,'SYS', decode(o1.object_type,'TABLE','SYSTEM TABLE','VIEW', 'SYSTEM VIEW', o1.object_type), 'SYSTEM', decode(o1.object_type,'TABLE','SYSTEM TABLE','VIEW', 'SYSTEM VIEW', o1.object_type), o1.object_type) table_type, null remarks
from all_objects o1
where o1.object_type in
('TABLE', 'VIEW') union select null table_qualifier, s.owner table_owner, s.synonym_name table_name, 'SYNONYM' table_type, null remarks
from all_objects o3, all_synonyms s
where o3.object_type in ('TABLE','VIEW') and s.table_owner= o3.owner and s.table_name = o3.object_name
union select null table_qualifier, s1.owner table_owner, s1.synonym_name table_name, 'SYNONYM' table_type, null remarks
from all_synonyms s1
where s1.db_link is not null )
tables
WHERE 1=1 AND TABLE_NAME='MYTAB1' AND table_owner='HUGO'
ORDER BY 4,2,3;
The query took:
- On-prem:
Elapsed: 00:00:00.24 - Cloud:
Elapsed: 00:00:02.56
Then, the customer modified it to access the DBA_-views instead of the ALL_-views.
select * from
(select null table_qualifier, o1.owner table_owner, o1.object_name table_name, decode(o1.owner,'SYS', decode(o1.object_type,'TABLE','SYSTEM TABLE','VIEW', 'SYSTEM VIEW', o1.object_type), 'SYSTEM', decode(o1.object_type,'TABLE','SYSTEM TABLE','VIEW', 'SYSTEM VIEW', o1.object_type), o1.object_type) table_type, null remarks
from dba_objects o1
where o1.object_type in ('TABLE', 'VIEW')
union
select null table_qualifier, s.owner table_owner, s.synonym_name table_name, 'SYNONYM' table_type, null remarks
from dba_objects o3, all_synonyms s
where o3.object_type in ('TABLE','VIEW') and s.table_owner= o3.owner and s.table_name = o3.object_name
union
select null table_qualifier, s1.owner table_owner, s1.synonym_name table_name, 'SYNONYM' table_type, null remarks
from dba_synonyms s1
where s1.db_link is not null ) tables
WHERE 1=1 AND TABLE_NAME='MYTAB1' AND table_owner='HUGO'
ORDER BY 4,2,3;
And the result was interesting then. Now, the modified query was quite on-par with the expected result.
- On-prem:
Elapsed: 00:00:00.09 - Cloud:
Elapsed: 00:00:00.34
At first, this is a smart customer. I like their approach a lot narrowing down things.
And of course, I had a quick recommendation, too.
My first reflex
I remembered some cases where the obvious solution were statistics or an underscore. For instance, I blogged about an old time zone problem where you had to use alter session set “_with_subquery”=materialize; to workaround the issue. Or an issue with ALL_SYNONYMS in Oracle 12c being quite slow. Proper stats collection was the solution.
So, I gave my usual recommendation to gather stats on the dictionary properly:
begin
dbms_stats.gather_schema_stats('SYS');
dbms_stats.gather_schema_stats('SYSTEM');
dbms_stats.gather_fixed_objects_stats;
end;
/
And it did solve … nothing.
In fact, the customer had gathered stats already – not directly on SYS and SYSTEM but they did think about it, too. I just had no effect. As I wrote before, smart customer. It would have been too easy this way.
The solution
Well. as said before, I love to learn new things. Later on Friday evening, Paloma and Jose, my colleagues from Oracle Spain in Malaga, contacted me with the solution. And Alex Zaballa from my own team confirmed right away that he has seen this issue multiple times in his previous life as a consultant. I have no idea why I haven’t seen it before – but now I know.
The solution was changing the value of the parameter CONTAINER_DATA. The documentation tells you:
Use CONTAINER_DATA to control whether queries on extended data-linked objects from within a PDB return rows from both the root and the PDB, or rows from only the PDB.
This parameter controls the behavior of queries on the following types of objects:
- Extended data-linked Oracle-supplied data dictionary objectsThis type of object stores data pertaining to the CDB root, as well as data pertaining to individual PDBs.When this type of object is queried from the CDB root, only data pertaining to the CDB root is returned.When this type of object is queried from a PDB, the value of the
CONTAINER_DATAinitialization parameter controls the query result as follows:
ALL: The query returns data pertaining to both the CDB root and the PDBCURRENT: The query returns only data pertaining to the PDBCURRENT_DICTIONARY: The query returns only data pertaining to the PDB
If you wonder why CURRENT and CURRENT_DICTIONARY have the same effect, there are differences for application common objects. See the documentation for further details, please.
More information, and no recommendation
Now I did check My Oracle Support and the BugDB of course. And I found some hits like this one:
- MOS Note: 2915211.1 – Query to ALL_SYNONYMS takes very long time after 19c upgrade)
- Recommendation: Set CONTAINER_DATA=CURRENT_DICTIONARY in both, CDB and PDB, to improve performance when you query dictionary objects. It links to bugs 32477224 and 26038007 as an example.
Still, don’t change the parameter now blindly but instead try to understand the implications, please:
- MOS Note: 2989081.1 – Since Container_data Is Not Set, The Common Users Can Only Query The Data of CDB$ROOT From the CDB_XXX View Which Is Different From the Query Result Of SYS User
- Tim Hall (oracle-base.com) on CONTAINER_DATA
Paloma showed me the execution time of the original query after the customer had changed CONTAINER_DATA=CURRENT:
- On-prem:
Elapsed: 00:00:00.24 - Cloud:
Elapsed: 00:00:00.04
Now it’s fast again – and faster than before in Oracle Cloud.
Let me emphasize that this blog post isn’t a recommendation to set this parameter generally. I use the blog as my memory dumpster which allows me to find things quicker in case they happen again. So, this may be useful and worth trying it out in case you hit a similar problem.
Further Links and Information
- Alex Zaballa: A Year of Transformation: Finding Balance, Health and Happiness at Oracle
- Oracle 19c Documenation: CONTAINER_DATA
- MOS Note: 2915211.1 – Query to ALL_SYNONYMS takes very long time after 19c upgrade)
- MOS Note: 2989081.1 – Since Container_data Is Not Set, The Common Users Can Only Query The Data of CDB$ROOT From the CDB_XXX View Which Is Different From the Query Result Of SYS User
–Mike
Configuring CONTAINER_DATA=current_dictionary became a standard on my job when moving to multitenant. There are come queries in the Health ERP that our clients use that ALWAYS became slow after the upgrade to 19c + CDB/PDB.
Thanks for confirming, Leonardo!
Cheers,
Mike
Lol, This sounds familiar.
I solved it differently by overruling the all_synonyms view with a per schema all_synonyms view on the user_synonyms view.
But thanks for the tip about container_data.
Thanks Jan, for the tip.
As written, I love to learn something new every day!
Cheers, and thanks for sharing,
Mike
Did some testing and found the below, which may be interesting side effect of setting this parameter
reference articles
Bug 33115892 – Use “container_data” Hint To Improve Query Performance For Sys.loader_dir_objs (Doc ID 33115892.8)
Bug 35323379 – ORA-13199: spatial index commit failure when container_data=current_dictionary or all (Doc ID 35323379.8)
Bug 31142749 – QUERY ON ALL_ARGUMENTS SLOW IN 19.
Since Container_data Is Not Set, The Common Users Can Only Query The Data of CDB$ROOT From the CDB_XXX View Which Is Different From the Query Result Of SYS User (Doc ID 2989081.1)
Slow Dictionary Query on ALL_ARGUMENTS (Doc ID 2707499.1)
‘No Object Found’ When Describing v$SQL in SQL*Developer (Doc ID 3024937.1)
https://forums.oracle.com/ords/apexds/post/sp2-0749-only-when-connecting-with-sql-developer-8392
Error message : SP2-0749: Cannot resolve circular path of synonym “v$SQL”
SQL Navigator : [1]:(Error): Cannot describe object: SYSADM.V$SQL
Note : This parameter CONTAINER_DATA was added in 19.10 but set to ALL to retain the default behavior
Values are below
ALL – this is the default. Data will be selected from ROOT and PDB.
CURRENT – data will be selected from current PDB only.
CURRENT_DICTIONARY – data from current PDB only but restrict this behavior to Oracle-supplied objects.
This MOS document better explains Slow Dictionary Query on ALL_ARGUMENTS (Doc ID 2707499.1)
then the official documentation : https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/CONTAINER_DATA.html
So the real difference between CURRENT and CURRENT_DICTIONARY is that
Current setting applies to both User Data and Dictionary objects
and
CURRENT_DICTIONARY applies to only Dictionary objects
Also General Recommendation is to set this to : CURRENT_DICTIONARY with the following words in support article
For most customers who feel the need to set this parameter, this is probably the value to use.
The below MOS document also describes this issue with PeopleSoft DDDAUDIT Report
E-INST: DDDAUDIT Performance Issue With Oracle 19c Pluggable Database (Doc ID 2919546.1)
and recommends this parameter to be set to CURRENT_DICTIONARY to resolve the performance issue.
More interesting this document
‘No Object Found’ When Describing v$SQL in SQL*Developer (Doc ID 3024937.1)
After the setting this parameter to CURRENT_DICTIONARY
desc V$SQL or desc DBA_SYNONYMS or desc ALL_SYNONYMS or desc DBA_SYNONYMS
fails with
SP2-0749: Cannot resolve circular path of synonym “v$SQL”
SP2-0749: Cannot resolve circular path of synonym “ALL_SYNONYMS”
SP2-0749: Cannot resolve circular path of synonym “USER_SYNONYMS”
SP2-0749: Cannot resolve circular path of synonym “DBA_SYNONYMS”
The same error appears in SQL Navigator
SQL Navigator Version : 8.0.0.408
SQL Developer Version : 24.3.1.347 Build 347.1826
VS Code SQL Navigator Extentsion
SQLCL 24.3.1.0 build: 24.3.1.344.2216
In SQL Developer I see the below error
[1]:(Error): Cannot describe object: SYSADM.V$SQL
However same desc v$SQL works fine with SQL PLUS (19.24) when using CONTAINER_DATA to CURRENT_DICTIONARY
Summary
Test it before setting this variable. It may fail certain queries or may not work correctly with certain Oracle or third party tools.
Certain applications may have recommendation to set it to CURRENT_DICTIONARY or ALL.
In my case I will set it to CURRENT_DICTIONARY for my individual Data dictionary query and also I noticed that DB with just 1 PDB does not show significant difference in performance.
In my testing performance improved by only 1 or 2 second.
I believe as number of PDBs increases, queries will show more performance degradation.
THANKS A LOT!!
Cheers,
Mike
How would this article benefit Users/Students/Beginners who might not be having access to the MoS?
Well … I think the article tells you the most important things already 🙂
Cheers,
Mike
Hello Mike,
We observered same behavior few years back when we upgraded to 19c and parameter CONTAINER_DATA =CURRENT_DICTIONARY is mandatory for PDB’s working fine for most of Oracle applications EBS,Siebel and so on for us.
Thank you for good post.
MJ
Thanks for your comment – this is helpful for me to hear!
Cheers,
Mike
Thanks for the suggestions although it may not resolve my case.
Working with Oracle since 1999 I still discover some new strange cases as it happened now after a current shortage in our datacenter with a customer’s database. And now everything is ok again but: the datapump export is more than 100 times slower than usual, consuming much cpu with two threads.
I have found your Internet page already different times and I like your “story telling” way as here with the “Friday afternoon calls”.
Arne
Sorry, Arne, that it didn’t resolve your issue 🙁
I can’t do magic unfortunately.
Cheers,
Mike