What they don’t tell you about Oracle SQL Profiles
August 4, 2007 at 4:38 pm | In Performance | 3 CommentsThere is a very useful performance tuning document on the EMC developer site here. The document describes the use of a new Oracle 10g facility called the SQL Tuning Advisor. The SQL Tuning Advisor analyses SQL statements for you and provides tuning recommendations. One of these recommendations could be a SQL Profile which is essentially a set of hints that, hopefully, guide the Oracle cost-based optimiser (CBO) to choose a more appropriate execution plan. SQL Profiles can be a very effective tool to address performance issues with slow database queries however they do have limitations when used with a Documentum system.
Changing Literals
SQL Profiles are applied by the database at query optimisation time. The text of the SQL is compared with any available profiles and if there is a match the hint information contained in the SQL Profile is taken into account by the CBO. Since the SQL needs to be an exact match there are going to be some situations where a SQL Profile is not appropriate. For example the following DQL may well come from some code to display the properties of the object.
select * from dm_relation where parent_id = '09fff99980001117'
Let’s suppose we have been asked to tune the performance of the queries run in this part of the code. When this query is run by Content Server it is transformed to SQL that probably looks like this:
select * from dm_relation_s where parent_id = '09fff99980001117'
Since the literal ‘09fff99980001117′ is likely to be different for every execution of the DQL it won’t be sensible to define a SQL Profile; the SQL will likely keep changing every time the code runs.
Now one possibility to consider is setting the Oracle CURSOR_SHARING parameter to FORCE or SIMILAR (although see Jonathan Lewis’ comment below about the force_match option in the SQL Profiles API). With these setting Oracle will transform all the literals in the SQL query into bind variables so that it looks something like this:
select * from dm_relation_s where parent_id = :"SYS_B_000"
Every execution of the DQL now produces the same SQL and a single SQL Profile would be effective.
dm_sysobject and its subtypes
A similar problem crops up when the query involves a dm_sysobject or sub-type. Consider this query:
select * from dm_document
If user JohnSmith, who is a member of 2 groups (group1 and group2), runs this query the resulting SQL might look like this. In order to enforce ACLs on the object being queried some extra predicates are added to the query. These predicates include literals for the user’s name and the groups they are a member of. So if user DaveJones, a member of 2 different groups (group3 and group4), runs the same DQL then the resulting SQL will look like this. Again the SQL is different and a SQL Profile that tunes the first query will not tune the second one.
The CURSOR_SHARING idea will fix this particular problem but notice that there is a further problem. If users are in different numbers of groups then different SQL is created. This is the typical SQL generated for JohnSmith or DaveJones when CURSOR_SHARING=FORCE. But for a user who is a member of 3 groups the SQL looks like this. Once more the SQL Profile that applies for users in 2 groups will not apply for users in 3 groups; the SQL is different.
You can of course attempt to create SQL Profiles that cover all possible group membership counts (and note this is membership both directly and indirectly of groups). But this strategy could quickly become unmanageable.
3 Comments »
RSS feed for comments on this post. TrackBack URI
Blog at WordPress.com. | Theme: Pool by Borja Fernandez.
Entries and comments feeds.
Robin,
If you bypass the GUI screens for accepting profiles and fall back to the pl/sql package (dbms_sqltune), 10gR2 has added a new option to the call which apparently does for profiles what cursor_sharing does for literal strings in SQL.
The following is an example of a call to accept a profile – using information from the relevant GUI screens, but note the force_match option. This should allow the optimizer to ignore the literals in a statement when trying to match a new statement with a stored one.
begin
dbms_output.put_line(
dbms_sqltune.accept_sql_profile(
task_name => ‘SQL_TUNING_1160988104234′,
name => ‘FORCED_SQL_PROFILE’,
replace => true,
force_match => true
)
);
end;
/
Regards
Jonathan Lewis.
Comment by Jonathan Lewis — August 10, 2007 #
Robin,
Comment by imjoebond — October 4, 2007 #
Now that I have your attention. Did you ever make any headway in addressing this situation? Particularly, the acl predicates varying depending on the groups a user might belong. My site has a blurb about CURSOR_SHARE on it, but like you said there is a limitation to how effectively you can manage the sql profiles/outlines. We actually backed it out and went with the other recommended dctm db tuning params. Generally, I see poor performance until a query is executed at least once. So a client would see poor performance on the first load of a screen and then see better performance on the next call.
Still looking for the silver bullet.
Cheers,
Joe
Comment by imjoebond — October 4, 2007 #