dynamic_sampling hint in queries causing issues in oracle 12c - oracle

We got told by dba that our application causes troubles on servers.
There are queries that start like following:
SELECT /* DS_SVC */ /*+ dynamic_sampling(0) no_sql_tune no_monitoring
optimizer_features_enable(default) no_parallel result_cache(snapshot=3600)
OPT_ESTIMATE(#"innerQuery", TABLE, "THIS_#21", SCALE_ROWS=0.0007347778778)
*/ SUM(C1) FROM ...
and they crash server, we receive ORA-12537.
We are using NHibernate, but I am fairly sure those queries are not generated by our application. The queries just have no meaning in business logic, they are some random joins. We don't have sql trace rights, but in logs that dba gives us those queries are executed under our module name.
I googled and found out that DS_SVC is a comment for some service queries that Oracle12 uses in dynamic sampling.
Our queries not exactly complex, couple of left joins with rownum limit 1000.
So the question is - can I say those DS_SVC queries are a problem on dba side? If so, where can I get some docs to prove it?

Looks like a 12c bug. See if changing this helps. Can ask Oracle support as well.
ALTER SESSION SET “_fix_control”=’7452863:0′
https://www.pythian.com/blog/performance-problems-with-dynamic-statistics-in-oracle-12c/
DYNAMIC_SAMPLING hint is used to let CBO collect
cardinality during run time.
Looks like algorithm has been changed in 12c and dynamic sampling is
triggered in a broader set of use cases. This behavior can be disabled
at statement, session or system level using the fix control for the
bug 7452863. For example, ALTER SESSION SET
“_fix_control”=’7452863:0′;

Those queries are generated by the optimizer itself. The feature is called "Dynamic sampling". Until 11g this was by default used only when there were no stats on tables.
Since 12c Dynamic sampling can also be triggered by other new feature "Adaptive execution plans". For example in situations where histograms are missing on columns.
Generally this is quite complex DBA stuff to deal with. There are various ways how to fix "Adaptive exec plans" or to disable them partially/completely.
Best you can do, is to contact Oracle support.

We have added /*+ dynamic_sampling(0) */ hint in our queries. It helped, the exception is gone.

Related

Oracle different plans for different users

I have a realy strange problem.
I'm using Oracle 11g.
There is a query executed by Business Objects tool, which the optimizer generate different plans for different users.
When my customer run the BO report it's realy slowly, but when I run it, it's fast.
According to the fact that there is a great plan (take seconds), I tried to enforced the optimizer to use that plan.
The problem is that it's not work.
I tried with baseline and sqlsets but the query used bind variables with different values each time, so it not realy help when the query change.
Is there a way to disable a plan for all sql executions?
This is 1 bad plan.. but can come with a lot of queries becasue of the bind variables.
More, I found in the net information about optimizer_secure_view_merging
parameter that could cause such problem.. but I have few users that got the good plan , not only the owner.. Is that still can be that ?
source:
https://oracledb.wordpress.com/2007/04/10/execution-plans-differents-with-different-users/
If there is another idea what to do..
I'd not call this problem a realy strange.
There is a lot of possible causes that diferent user get different behaviour for the same query.
On trivial cause is to query a non-qualified table.
select * from TAB
This query will access different tables for different users.
The next possibility are different Optimizer Initiation Parameters that could cause that the optimizer for one user may use features that are prohibited for other user.
I'd recommend as a simplest way for troubelshooting to perform the Oracle 10053 trace for both queries.
The trace file contains the complete list of the used paramaters and a simple diff could provide a usefull hint.
If the parameters are not the cause, you'll see in the trace the details why different access paths in the execution plan was taken. (A good introduction to understand 10053 trace is the paper of Wolfgang Breitling I linked above).

Oracle not uses best dbplan

i'm struggeling with Performance in oracle. Situation is: Subsystem B has a dblink to master DB A. on System B a query completes after 15 seconds over dblink, db plan uses appropriate indexes.
If same query should fill a table in a stored procedure now, Oracle uses another plan with full scans. whatever i try (hints), i can't get rid of these full scans. that's horrible.
What can i do?
The Oracle Query Optimizer tries 2000 different possibilities and chooses the best one in normal situations. But if you think it choose wrong plan, You may suspect the following cases:
1- Your histograms which belongs to querying tables are deprecated.
2- Your indexes can not be used because of your faulty query.
3- You can use index hints to force the indexes to be used.
4- You can use SQL Advisor or run TKProf for performance analysis and decide what's wrong or what caused bad performance. Check network, Disk I/O values etc.
If you share your query we can give you more information.
Look like we are not taking same queries in two different conditions.
First case is Simple select over dblink & Second case is "insert as select over dblink".
can you please share two queries & execution plans here as You may have them handy. If its not possible to past queries due to security limitations, please past execution plans.
-Abhi
after many tries, I could create a new DB Plan with Enterprise Manager. now it's running perfect.

Oracle Bind Query is very slow

I have an Oracle bind query that is extremely slow (about 2 minutes) when it executes in my C# program but runs very quickly in SQL Developer. It has two parameters that hit the tables index:
select t.Field1, t.Field2
from theTable t
where t.key1=:key1
and t.key2=:key2
Also, if I remove the bind variables and create dynamic sql, it runs just like it does in SQL Developer.
Any suggestion?
BTW, I'm using ODP.
If you are replacing the bind variables with static varibles in sql developer, then you're not really running the same test. Make sure you use the bind varibles, and if it's also slow you're just getting bit by a bad cached execution plan. Updating the stats on that table should resolve it.
However if you are actually using bind variables in sql developers then keep reading. The TLDR version is that parameters that ODP.net run under sometimes cause a slightly more pessimistic approach. Start with updating the stats, but have your dba capture the execution plan under both scenarios and compare to confirm.
I'm reposting my answer from here: https://stackoverflow.com/a/14712992/852208
I considered flagging yours as a duplicate but your title is a little more concise since it identifies the query does run fast in sql developer. I'll welcome advice on handling in another manner.
Adding the following to your config will send odp.net tracing info to a log file:
This will probably only be helpful if you can find a large gap in time. Chances are rows are actually coming in, just at a slower pace.
Try adding "enlist=false" to your connection string. I don't consider this a solution since it effecitively disables distributed transactions but it should help you isolate the issue. You can get a little bit more information from an oracle forumns post:
From an ODP perspective, all we can really point out is that the
behavior occurs when OCI_ATR_EXTERNAL_NAME and OCI_ATR_INTERNAL_NAME
are set on the underlying OCI connection (which is what happens when
distrib tx support is enabled).
I'd guess what you're not seeing is that the execution plan is actually different (meaning the actual performance hit is actually occuring on the server) between the odp.net call and the sql developer call. Have your dba trace the connection and obtain execution plans from both the odp.net call and the call straight from SQL Developer (or with the enlist=false parameter).
If you confirm different execution plans or if you want to take a preemptive shot in the dark, update the statistics on the related tables. In my case this corrected the issue, indicating that execution plan generation doesn't really follow different rules for the different types of connections but that the cost analysis is just slighly more pesimistic when a distributed transaction might be involved. Query hints to force an execution plan are also an option but only as a last resort.
Finally, it could be a network issue. If your odp.net install is using a fresh oracle home (which I would expect unless you did some post-install configuring) then the tnsnames.ora could be different. Host names in tnsnams might not be fully qualified, creating more delays resolving the server. I'd only expect the first attempt (and not subsequent attempts) to be slow in this case so I don't think it's the issue but I thought it should be mentioned.
Are the parameters bound to the correct data type in C#? Are the columns key1 and key2 numbers, but the parameters :key1 and :key2 are strings? If so, the query may return the correct results but will require implicit conversion. That implicit conversion is like using a function to_char(key1), which prevents an index from being used.
Please also check what is the number of rows returned by the query. If the number is big then possibly C# is fetching all rows and the other tool first pocket only. Fetching all rows may require many more disk reads in that case, which is slower. To check this try to run in SQL Developer:
SELECT COUNT(*) FROM (
select t.Field1, t.Field2
from theTable t
where t.key1=:key1
and t.key2=:key2
)
The above query should fetch the maximum number of database blocks.
Nice tool in such cases is tkprof utility which shows SQL execution plan which may be different in cases above (however it should not be).
It is also possible that you have accidentally connected to different databases. In such cases it is nice to compare results of queries.
Since you are raising "Bind is slow" I assume you have checked the SQL without binds and it was fast. In 99% using binds makes things better. Please check if query with constants will run fast. If yes than problem may be implicit conversion of key1 or key2 column (ex. t.key1 is a number and :key1 is a string).

Actively tracking oracle query performance

Background:
We have a database environment where views are calling views which are calling views... the logic has become complex and now changes to underlying views can have significant impact on the top view being called by the client application.
Now while we are documenting all the logic and figuring out how to unwind everything development continues on and performance continues to degrade.
Currently I would manually run an explain plan on a client query and dig into tuning it. This is a slow and tedious process and changes may not be examined for ages.
Problem:
I want to generate a report that lists SQL ID and lists changes in actual time/discrepancy between estimated rows and actual rows/changes in buffers/changes in reads in comparison to the average computed over the last month.
I would generally run the following script manually and examine it based just on that day's response.
ALTER SESSION SET statistics_level=all;
set linesize 256;
set pagesize 0;
set serveroutput off;
-- QUERY
SELECT
*
FROM
table (DBMS_XPLAN.display_cursor (NULL, NULL, 'ALLSTATS LAST'));
What I am trying to do is see about automating the explain plan query and inserting the statistics into a table. From there I can run a regression report to detect changes in the performance which can then alert the developers.
I was thinking something like this would be common enough without having to resorting to the OEM. I can't find anything so I wonder if there is a more common approach to this?
Oracle provides functionality for this with the Automatic Workload Repositiory. http://docs.oracle.com/cd/E11882_01/server.112/e16638/autostat.htm
It's an extra license on top of Enterprise Edition though, I believe. It ought to be usable in non-production environments without additional cost, but check with your Oracle sales rep.
It sounds like you are on the road to re-inventing STATSPACK. Oracle still include this in their database but don't document it any more, presumably because it's free, unlike AWR and ASH. You can still find the documentation in the 9i manual.
Active Session History (ASH) is what you are looking for
select * from v$active_session_history where sql_id = :yoursqlid

Does Oracle use Intermediate Resultsets like SQL Server or Sybase?

SELECT LASTNAME, STATE, COUNT(*)
FROM TEST
WHERE STATE IN ('NY','NJ','CA')
GROUP BY STATE,LASTNAME
HAVING COUNT(*)>1;
Similar query in MS SQL server and Sybase used to process internally as follows,
On Test table where clause is applied and resultset(internal table) is made, then a group by is applied and another internal resultset is made and then finally Having is applied and final result set is shown to the user.
Does Oracle use the resultset approach as well or is it something different?
By the way I tried to Google around, checked Oracle documentation, couldn't find the detail I was looking for. Sybase documentation is pretty clear on such things.
You can count on Oracle to materialize the result set in this case. To be sure, check the plan. I'm betting you will find a hash group by and then a filter operation at the top.
There may be some rare variations of your case that could be solved by walking a suitable index in order to avoid the intermediate result set, but I have never come across it in an execution plan.

Resources