I am working with legacy SQL code and I am finding a lot of queries like the following:
SELECT --+rule
username,
usernotes
FROM
userinfotable
ORDER BY
username
I read the Oracle Optimizer Hints documentation, but I can't find an exact reference for a --+rule. I am thinking this rule is possibly an obsolete artifact from a code generation tool that may have been designed to replace "--+rule" with user or generated /*+ SQL */ hint code.
What do you think? Does the --+rule code [literally] in the above example actually do anything as-is? or can I just discard it?
Platform = Delphi 6 with Direct Oracle Access components, Oracle 10g2 with last supported updates. Most of the Legacy SQL code was developed when using Oracle 7 and 8.
The answer is in the referenced documentation you have given:
The following syntax shows hints contained in both styles of comments
that Oracle supports within a statement block.
{DELETE|INSERT|MERGE|SELECT|UPDATE} /*+ hint [text] [hint[text]]... */
or
{DELETE|INSERT|MERGE|SELECT|UPDATE} --+ hint [text] [hint[text]]...
The --+ hint format requires that the hint be on only one line.
So it was an allowed syntax rule for hints: but I think I have never seen it.
In Oracle SQL "rule" hint means use the Rule Based Optimizer (RBO) instead of CBO (Cost Based Optimizer): since Oracle 10 it is no more supported. So for Oracle you cannot discard it: it should be taken into account but without support ...
10.2 doc says:
Rule-based Optimization (RBO) Obsolescence
RBO as a functionality is no longer supported. RBO still exists in
Oracle 10g Release 1, but is an unsupported feature. No code changes
have been made to RBO and no bug fixes are provided. Oracle supports
only the query optimizer, and all applications running on Oracle
Database 10g Release 1 (10.1) should use that optimizer. Please review
the following Oracle Metalink desupport notice (189702.1) for RBO:
http://metalink.oracle.com/metalink/plsql/ml2_documents.showDocument?p_
database_id=NOT&p_id=189702.1
You can also access desupport notice 189702.1 and related notices by
searching for "desupport of RBO" at:
http://metalink.oracle.com
Notice 189702.1 provides details about the desupport of RBO and the
migration of applications based on RBO to query optimization.
Some consequences of the desupport of RBO are:
CHOOSE and RULE are no longer supported as OPTIMIZER_MODE initialization parameter values and a warning is displayed in the
alert log if the value is set to RULE or CHOOSE. The functionalities
of those parameter values still exist but will be removed in a future
release. See "OPTIMIZER_MODE Initialization Parameter" for information
optimizer mode parameters.
ALL_ROWS is the default value for the OPTIMIZER_MODE initialization parameter.
The CHOOSE and RULE optimizer hints are no longer supported. The functionalities of those hints still exist but will be removed in a
future release.
Existing applications that previously relied on rule-based optimization (RBO) need to be moved to query optimization.
Related
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.
the analysis was working on version 10, after migration to version 11, it started giving error
[nQSError: 14025] No fact table exists at the requested level of detail
11g is more strict that 10g was in terms of a conformed data model. These types of errors almost always stem from something in the BMM being set up incorrectly, so I would start there. There are several things it could be.
Check your levels on the LTS being used. Set any levels to total for things you want the LTS to work with, but that it does not join to. This will force OBIEE to ignore that item in the join criteria, since there is no join. Set these levels on the column as well.
If you have levels set to detail, make sure the physical join actually exists.
Run a consistency check, and look for any warnings where it says no physical join, or logical tables source joins table at incorrect grain (I can't remember the exact wording, but you will know it when you see it).
Compare the queries generated in 10g ana 11g, or at least take a look at the query generated in 11g and look at your RPD.
Regards
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).
I found this document on the official ORACLE page while searching for information on Computed/Automatic/Virtual Columns:
http://www.oracle.com/technetwork/database/rdb/automatic-columns-132042.pdf
(Title: "Guide to Using SQL: Computed and Automatic Columns. A feature of Oracle Rdb")
Can anyone tell of these features really exist in ORACLE (I'm using version 10g, the document says Computed/Automatic is there since 7.1)?
I can't get any of the examples to work. Also the SQL formatting and syntax highlighting with ORACLE SQL Developer (v 3.0.04) does not work on these statements.
The document does not state that it is a tech-preview or something like that and according to the last page it has been around since May 2002.
For me it reads like a very early preview of 11g's VIRTUAL COLUMNS. What do you think?
Thanks,
Blama
You're reading the documentation of another product: Rdb (this is not Oracle Database Server)!
When you write rather complex SQL for Oracle, sooner or later you will have to apply the odd execution hint because Oracle can't seem to figure out the "best" execution plan itself.
http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm
Now this is certainly not a SQL standard. But still, I'm wondering, are there any other RDBMS that support these kinds of hints, and I really mean hints that are "embedded" in SQL? Are they similar, syntactically (i.e. also placed between the SELECTkeyword and the first selected COLUMN)? Do you know of a general documentation page comparing hints in various RDBMS?
N.B: I'm mostly interested in these RDBMS: Postgres, MySQL, HSQLDB, H2, Derby, SQLite, DB2, Sybase, SQL Server
I know that in db2 the plans are made fixed in some way, not how. In Oracle 11g there are other options besides adding hints to queries. These are SQLProfiles and SQLPlan Baselines, both very powerful. I just finished a performance tuning project where we did not add even a single hint to the code, on the contrary.
You can add Oprimizer Hints to any SQL Server Query
The PLAN clause allows you to define a particular plan to your query in Firebird.
AFAIK, nothing standard nor close to it, but in general, you can do this in a lot of RDBM's, but not all.
I'd also remind you, if you are making some sort of comparison with other DB platforms, that hints in Oracle are entirely non-binding. Which is to say that Oracle is free to disregard your hint if it so chooses.
Hints can be helpfull but I find that I rarely use them anymore - at least not compared to the past when I was working with the older optimizers in earlier Oracle versions. Back then hints were much more of a staple to performance tuning than they are now.