Skip to Main Content
  • Questions
  • Are private synonyms bad for performance?

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Arun.

Asked: January 28, 2003 - 9:16 pm UTC

Last updated: February 01, 2011 - 9:45 am UTC

Version: 8.1.7

Viewed 10K+ times! This question is

You Asked

Tom
I have all tables in schema x and all users connect to the database as user y. I have created private synonyms owned by user y for every table owned by x. As a result, instead of select * from x.t1, users just have to type select * from t1 where t1 is a synonym for x.t1. Would this lead to poor performance? There are about 150 tables.
Thanks


and Tom said...

Private synonyms are much less evil then public.

Public pollute the global namespace, lead to confusion -- that is my issue with them.

Private -- well, they do not pollute the namespace, no confusion and no real overhead.


Rating

  (11 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Arun Gupta, January 29, 2003 - 6:44 pm UTC

I agree. We share database environments among projects and there are tables with same names in different projects with totally different business use and structure. The public synonyms were a big headache, so we decided to switch to private synonyms. As you said, they are clean and contained within a schema. I did a test case with sql_trace and tkprof. It turned out that private synonyms took 2.5% to 4% more execution time. This doesn't seem to be a big overhead. Let's see if I can convince client.
Thanks very much...!!

Help needed !!

Arun Gupta, February 01, 2003 - 11:04 pm UTC

Tom
Help. In reply to another question "Poor performance using public synonyms" elsewhere in your forum, you have refuted claims by Steve Adams article about public synonyms and private synonyms being several times slower than object access by fully qualified name. The hyperlink to the article is:
</code> http://www.ixora.com.au/newsletter/2001_05.htm <code>
where a partial test case is provided. This article is being quoted by the client to ask us to drop private synonyms. However, I conducted the tests described in the article by creating 960 one column tables, inserting one row into each of these tables and tracing the user session using sql_trace and tkprof. I cannot find the kind of difference between public and private synonyms as indicated in the article. My other test cases using select statements indicate less than 4% difference if I use private synonyms vs. no synonyms at all.

If it is not too much trouble, can you please repeat the test case described on IXORA site to lay the matter to rest permanently.

Another problem: Since this question is not entered in the forum, how can I see all the responses posted? If I click on the link I got with the first answer, I just see my question and your first answer. Is there a way to see the entire thread?

Thanks...

Tom Kyte
February 02, 2003 - 10:16 am UTC

when I click on the "followup" button and send you an email (the one you just got), you should be seeing the WHOLE thing -- if not, please send me the email you just recieved and I'll see why not....

Anyway, I've run his test in 9iR2 and find (as measured by v$mystat):

  
       Hard Parse Performance


               NO synonyms          private synonyms         public synonyms
CPU            168                  165                      171
row cache      25,920               27,840                   29,818
shared pool    27,162               29,124                   31,240
library cache  21,287               27,048                   33,213<b>
TOTAL LATCHES  127,054              142,659                  161,192</b>


        Soft Parse Performance


               NO synonyms          private synonyms         public synonyms
CPU            81                   83                       83
row cache      20,160               20,160                   20,218
shared pool    7,786                7,787,                   8,013
library cache  15,453               15,454                   15,852<b>
TOTAL LATCHES  82,676               83,232                   85,708</b>


So, I do not see the egregious results he does on the soft parse, however, I zero in on the total latches personally -- as latched = locks = scalability killers.

During the hard parse -- it is clear, no synonyms use 20-25% less latches, during the soft parse, about 5% less.


But my major gripe with synonyms has never been purely performance based.  When used JUDICIOUSLY (in small quantities), they can be good.  Hey -- I use them on asktom -- that procedure F you see in my urls?  that's a public synonym -- but it is the ONLY one, everything else is a qualifitied schema call.

My gripe is the namespace pollution, the confusion, the human errors it lends itself towards -- not so much the performance -- although that is a consideration.


Here is my test script -- should run in at last 817 and up:


spool test

set echo on

define NITERS=&1

@connect /

drop table run_stats;
create table run_stats
( runid varchar2(20), what varchar2(10), name varchar2(80), value int );
REM pause

create or replace view run_stats_report
as
select runid, what, name, diff, sum(diff) over(partition by what) tot
  from (
select b.runid, b.what, b.name, b.value-a.value diff
  from run_stats a, run_stats b
 where a.name = b.name
   and a.what = b.what
   and a.runid = 'before'
   and b.runid <> 'before'
   and b.value-a.value <> 0
       )
 order by what, diff
/
REM pause

create or replace procedure save_stats( p_str in varchar2 )
as
begin
    if (p_str = 'before')
    then
        delete from run_stats;
    end if;
    insert into run_stats (runid, what, name, value)
    select p_str, stats.*
      from ( select 'STAT', a.name, b.value
               from v$statname a, v$mystat b
              where a.statistic# = b.statistic#
              union all
             select 'LATCH', name,  gets
               from v$latch ) stats;
end;
/
REM pause

grant execute on save_stats to public;




drop user tbl_owner cascade;
begin
    for x in ( select synonym_name from dba_synonyms where synonym_name like 'SYNTEST_T%' )
    loop
        execute immediate 'drop public synonym ' || x.synonym_name;
    end loop;
end;
/
drop user u1 cascade;
drop user u2 cascade;
REM pause


grant dba to tbl_owner identified by tbl_owner;
alter user tbl_owner default tablespace assm;

grant dba to u1 identified by u1;
grant dba to u2 identified by u2;
REM pause



@connect tbl_owner/tbl_owner

begin
    for i in 1 .. &NITERS
    loop
        execute immediate 'create table syntest_t' || i || ' ( x number )';
        execute immediate 'create public synonym syntest_t' || i || ' for syntest_t' || i;
    end loop;
end;
/
REM pause


@connect u1/u1

begin
    for i in 1 .. &NITERS
    loop
        execute immediate 'create synonym syntest_t' || i || ' for tbl_owner.syntest_t' || i;
    end loop;
end;
/
REM pause


alter system flush shared_pool;

begin
    for i in 1 .. &NITERS
    loop
        execute immediate 'insert into syntest_t' || i || ' values (1)';
   end loop;
end;
/
REM pause

exec ops$tkyte.save_stats( 'before' );
begin
    for i in 1 .. &NITERS
    loop
        execute immediate 'insert into syntest_t' || i || ' values (0)';
    end loop;
end;
/
exec ops$tkyte.save_stats( 'after hard privsyn' );
select * from ops$tkyte.run_stats_report;
REM pause


exec ops$tkyte.save_stats( 'before' );
begin
    for i in 1 .. &NITERS
    loop
        execute immediate 'insert into syntest_t' || i || ' values (0)';
    end loop;
end;
/
exec ops$tkyte.save_stats( 'after soft privsyn' );
select * from ops$tkyte.run_stats_report;
REM pause



@connect u2/u2

alter system flush shared_pool;

begin
    for i in 1 .. &NITERS
    loop
        execute immediate 'insert into syntest_t' || i || ' values (1)';
    end loop;
end;
/
REM pause

exec ops$tkyte.save_stats( 'before' );
begin
    for i in 1 .. &NITERS
    loop
        execute immediate 'insert into syntest_t' || i || ' values (0)';
    end loop;
end;
/
exec ops$tkyte.save_stats( 'after hard pubsyn' );
select * from ops$tkyte.run_stats_report;
REM pause


exec ops$tkyte.save_stats( 'before' );
begin
    for i in 1 .. &NITERS
    loop
        execute immediate 'insert into syntest_t' || i || ' values (0)';
    end loop;
end;
/
exec ops$tkyte.save_stats( 'after soft pubsyn' );
select * from ops$tkyte.run_stats_report;
REM pause


@connect /


alter system flush shared_pool;

begin
    for i in 1 .. &NITERS
    loop
        execute immediate 'insert into tbl_owner.syntest_t' || i || ' values (1)';
    end loop;
end;
/
REM pause

exec ops$tkyte.save_stats( 'before' );
begin
    for i in 1 .. &NITERS
    loop
        execute immediate 'insert into tbl_owner.syntest_t' || i || ' values (0)';
    end loop;
end;
/
exec ops$tkyte.save_stats( 'after hard NOsyn' );
select * from ops$tkyte.run_stats_report;
REM pause


exec ops$tkyte.save_stats( 'before' );
begin
    for i in 1 .. &NITERS
    loop
        execute immediate 'insert into tbl_owner.syntest_t' || i || ' values (0)';
    end loop;
end;
/
exec ops$tkyte.save_stats( 'after soft NOsyn' );
select * from ops$tkyte.run_stats_report;

spool off
 

Dummy comment to view response to follow up question

A reader, February 03, 2003 - 6:41 pm UTC


Thanks!!

Arun Gupta, February 03, 2003 - 7:07 pm UTC

Tom
Thanks a lot...I also did some testing but nothing close to as extensive as you have done. I also got similar results. Now when I face the development team, I will have test results to back up the recommendation to keep private synonyms to minimum and where absolutely necessary. We do not use public synonyms at all. I personally do not want to make any recommendations unless backed by solid reasoning and repeatable, substantiated numbers. Your test cases provides precisely that kind of insight into working of Oracle. Sorry about posting the dummy link. The reply link you sent works just fine.

Thanks again...

Concurrency and Users

Jonathan Lewis, February 04, 2003 - 5:39 am UTC

I think one of the issues that makes it hard to test the impact of "public/private/fully qualified/become user" is the need for emulating the correct usage.

I believe that the most significant point in Steve's article relates to the production of increasinng numbers of objects in the library cache as the number of users increases, and the increasing impact this has on the LENGTH OF TIME that latches are held as the concurrency goes up.

The library cache will hold various structures relating to object definitions (such as private synonyms, and negative dependencies for public synonyms), and object permissions.

On a small test, with one user, you can count the latch accesses and see significant differences that may not appear to be terribly threatening . But with large numbers of users, the number of 'clones' of objects with the same name in the same namespace and therefore on the same latch, goes up, and the time taken to search a chain can become a serious threat if everyone is trying to access some information about their verion of the 'same' object. The scale of the problem is order n-squared with respect to the number of different users.



Can these be considered "small quantities"?

Frédéric, September 26, 2007 - 7:22 pm UTC

Hi Tom,
we are currently running a database which is designed like this:

SQL> conn system/manager@ind30
Connect¿.
SQL> select count(*) from dba_synonyms;

 COUNT(*)
---------
   657112

SQL> select count(*) from dba_users;

 COUNT(*)
---------
      437

SQL> select count(distinct owner) from dba_tables;

COUNT(DISTINCTOWNER)
--------------------
                  16

SQL> select count(distinct object_name) from dba_objects;

COUNT(DISTINCTOBJECT_NAME)
--------------------------
                      6745

SQL> select count(distinct object_name) from dba_objects where owner not in ('SYS', 'SYSTEM');

COUNT(DISTINCTOBJECT_NAME)
--------------------------
                      5368

As you may have already guessed, our users are accessing tables and packages through private synonyms.
Do you think that we are no longer "judicious", that we've gone beyond "small quantities"?
Can we expect some gain by using public synonyms or by suppressing all our synonyms and issuing "alter session set current_schema=xxxx" commands instead ? 

Tom Kyte
September 26, 2007 - 10:20 pm UTC

are you experiencing some performance issue you have related back to latching wait events related to synonym resolution?

Too big a quantity

A reader, October 06, 2007 - 7:53 pm UTC

...Sorry, it took some time to get the answer from our DBAs.
Apparently no. We are experiencing performance issues, but they do not seem to be due "to latching wait events  related to synonym resolution".
...but...
as a consultant had said that we should get rid of those 600000 or so synonyms which polluted our system tablespace -which was about 800Mo big-, we've tried to drop them, and suceeded.
Everything went fine, until the pmon process woke up a few hours later... and everything froze. After an hour or so during which nobody could connect or work properly, we've decided to shut down the database, to see if a little "startup" would do it some good. It did.
But as the same phenomenon happened the next day, and as the next startup didn't help this time, we were forced to rebuild the database from scratch by exporting and reimporting it.

Since the pmon process seems unable to handle the deletion of 600000 synonyms, I would finally say that using 600000 synonyms is no longer judicious.
Your opinion ?

SQL> select * from v$version;
...
Oracle8i Enterprise Edition Release 8.1.7.4.0 - 64bit Production

Are private synonyms bad for performance? version 10.2.0.4

Pasha, August 09, 2009 - 6:01 am UTC

Tom,

We are building a new application on two existing schemas LTS and MSS and the total objects in both schemas are about 900.

We have created a new user APPUser for the new application and created private synonyms for all 900 objects from both
schemas LTS and MSS.
Since we in the development stage:
is it good to use private synonyms or to use LTS.t1? which one is the best in related to performance.
Thanks
Tom Kyte
August 11, 2009 - 1:35 pm UTC

private are better than public, both from a "performance" hit as well as "namespace" hit.

If you have to use them, go ahead. I myself have not had problems using actual schema names in most cases (meaning, you can select * from scott.emp instead of create private synonym emp for scott.emp and then select * from emp)

Performance of Private synonym

OracleBAbu, January 22, 2011 - 2:46 am UTC

Tom,
To modularize our schema based on functionality, we are dividing our schema into multiple schemas.
In some places where one schema requires object of other schema ,We are providing access(Private Synonyms)
CurrentSchema =
Funct1Schema + Funct2Schema + Funct3Schema
If Funct1Schema requires an object from Funct2Schema then access for the corresponding object will be given to Funct1Schema from Funct2Schema .

Will there be any performance issues here, while accessing the object of other schema?

thanks in Advance
Tom Kyte
February 01, 2011 - 9:45 am UTC

There will be a slight, marginal, almost non-detectable extra step during the hard parse. Short of that - no, there won't be a performance impact.

Private synonyms are much less evil than public - as stated above. They are fine.

Public synonyms should be avoided.

Reason to use synonyms?

A reader, July 21, 2014 - 6:25 pm UTC

Tom,

In our environment, the common approach for application development (whether in stored procedures or application code external to the database) has always been fully qualified schema name -- that is owner.table_name. The tables are accessed from a second application account, with a name such as app. However, some of our applications would like to have second or third or fourth (or more!) schemas for development and/or testing purposes.

When the additional schemas live in separate databases, there is no problem with the exact same code (using the same schema name) accessing the database. They both reference owner.table_name. However, when we consolidate schemas into a single database, and we have to change the schema owner name, so that we have owner and owner2, this causes application teams to fix all their code to point to owner2 for the second schema (used by app2).

There is a proposal to use private synonyms owned by app and app2, pointing to objects owned by owner and owner2, respectively. Then, rather than fully qualifying code with "owner.", the code would instead simply refer to the table name.

What are you thoughts about this? Good idea or bad?

There has been a proposal

A reader, December 25, 2014 - 5:30 pm UTC

Tom -- I had a further piece of information to add to my last question regarding the use of private synonyms rather than fully qualifying schema names in application code (whether in stored procedures or in code stored elsewhere). In an Agile development methodology, it is important to be able to quickly replicate the master schema for the developer to do his own work in his own sandbox. It would seem that synonyms would assist in this environment too. Thoughts on this and the last comment?

Thank you for all your time.