I am new to tuning and I am trying hard learn things as Oracle is like an ocean.
I have a query built on views that is running longer. I have query like:
select t2.col1,t2.col2
from vw_tab1 t1,vw_tab1 t2,tab3 t3
where t1.col3=123
and t2.col3<>123
and t2.col4=t1.col5
AND t3.col2=t2.col2;
We are using single view multiple times in the same query. Does this run the query in view twice? Suggestions much appreciated. I am running this query in Oracle 11g single instance database.
Yes, the tables that make up the view vw_tab1 will be queried twice, once for each instance ( t1 and t2 ). If you were to issue an explain plan of your statement, you should see oracle querying the tables that make up the view, not the actual view.
Related
Recently I need to create several materialized views on Oracle 19c, all of the base tables are locate on a remote oracle database, the query uses dblink to connect the tables, and fast refresh is not allowed.
Most of them can complete refreshment in seconds after add some hints on them, like use_hash etc. But when create the one with union on the query, the hints do not work at all, luckily there is only one union, so I split the query to two parts, but another issue emerges, one of the materialized view only takes no more than 10 seconds for creation, but it takes hours even days cannot complete refreshment. I searched on web and got below answers:
use dbms_mview.refresh(mv_name, 'C', atomic_refresh=>false). This solution does not work.
fast refresh. The solution does not allowed.
Instead to do refresh, re-create the materialized view every time, it is a workaround, but not a solution.
Use hint optimizer_features_enable(9.0.0), I simulated the issue on a table (as I cannot insert into...select... on materialized view), seems the hint does work, but when I tried to apply the hint on the materialized view, from the execution plan I can see that the hint has been ignored. I also tried to add alter session set optimizer_features_enable='9.0.0' on scheduler job before the dbms_refresh.refresh(mv_name), but it does not work. Would like to know are there anyone have any idea on this problem? Thank you.
Jonathan from oracle community just gave me a solution for my specific query. As all the fields of my query come from remote database except the systimestamp function, so I can separate the function to the outer select statement and make all the remote fields as sub-select statement then add no_merge hint to it, this will make remote database optimizer come to play.
SELECT systimestamp, v.*
FROM (
my original query with /*+ no_merge */
) v;
I understand that a view is a window to an underlying table or set of tables in Oracle. For instance if I have a view that is created by joining multiple tables , will the view perform the actual join operations when I select data from the view? Does a view perform better than joining multiple tables to fetch data or is it the same with respect to performance?
There is usually no performance difference between a single query and a logically equivalent query that uses views.
Oracle has optimizer transformations that can combine views with the outer query; predicate pushing, simple and complex view merging, etc. Think of views more like a text macro that builds a large query, instead of a function that returns rows.
For example, in the below query Oracle would probably be smart enough to push the predicate on the primary key column into the view. Although the view by itself might return millions of rows, when the entire query is run Oracle will apply the predicate on the primary key column first.
select *
from view_returns_millions_of_rows
where primary_key_value = 1;
This question already has an answer here:
Is there a way to force Oracle to change a query's plan without using hints?
(1 answer)
Closed 3 years ago.
I have a oracle sql query and it has access plan attached to it. How can i change the access plan without changing the sql query. I think oracle has database table that store sql id and plan id , updating the plan id to new plan id will force the sql query to use different explain plan.
I am using Oracle 10, In this case i don't want to touch the existing query. I will write another query with hints and get the desired explain plan created. now I will use the new marker for the explain plan and attach it to the original sql id. This is the logic how to do this, but i dont know what all tables need to be updated to achieve this. Step1 : SQLI_D1 -> PLAN_ID1; Step2 : SQL_ID2 -> PLAN_ID2; STep3 : SQL_ID1 - > PLAN_ID2
There are too many answers, since your question is too broad. And you haven't even mentioned the DB version.
You said :
updating the plan id to new plan id will force the sql query to use
different explain plan.
No. The PLAN_HASH_VALUE is assigned by Oracle. It is a marker to relate an EXECUTION PLAN with the respective SQL_ID. If you want to force the OPTIMIZER to take a different execution plan of your choice, you could use HINTS in your query.
If you have pinned or preserved the execution plan for the SQL using stored outlines etc., also known as PLAN STABILITY, then you need to remove it, so that Oracle would be able to find a proper execution plan in it's next execution. And then, if required, you can stabilize the better plan as you think so.
Explain plan depends on its query and also on the statistics. For example oracle won't use an index if there is only one record in the table but it will use the index if there is a lot of records in the table and you extract only few of them. So you need to gather the statistics as much as possible.
But I don't understand your intention to force oracle recalculate the explain plan, Oracle knows how to access your tables based on the statistics you provide. Do not use hints like INDEX and other that tell oracle how to access tables. You can give oracle a hint that to tell oracle that you need only top 5 rows, and oracle will return them to you as fast as it can.
My manger just told me that having joins or where clause in oracle query doesn't affect performance even when you have million records in each table. And I am just not satisfied with this and want to confirm that.
which of the following queries is better in performance on oracle and in postgresql also
1- select a.name,b.salary,c.address
from a,b,c
where a.id=b.id and a.id=c.id;
2- select a.name,b.salary,c.address
from a
JOIN b on a.id=b.id
JOIN C on a.id=c.id;
I have tried Explain in postgresql for a small data set and query time was same (may be because I have just few rows) and right now I have no access to oracle and actual database to analyze the Explain in real envoirnment.
Using JOINS makes the code easier to read, since it's self-explanatory.
In speed there is no difference (I have just tested it) and the execution plan is the same
If the query optimizer is doing its job right, there should be no difference between those queries.
They are just two ways to specify the same desired result.
We have some Materialized views in our Oracle 9i database that were created a long time ago, by a guy no longer working here. Is there an easy (or any) method to determine whether Oracle is using these views to serve queries? If they aren't being used any more, we'd like to get rid of them. But we don't want to discover after the fact that those views are the things that allow some random report to run in less than a few hours. The answer I'm dreaming of would be something like
SELECT last_used_date FROM dba_magic
WHERE materialized_view_name = 'peters_mview'
Even more awesome would be something that could tell me what actual SQL queries were using the materialized view. I realize I may have to settle for less.
If there is a solution that requires 10g, we are upgrading soon, so those answers would be useful also.
Oracle auditing can tell you this once configured as per the docs. Once configured, enable it by "AUDIT SELECT ON {name of materialized view}". The audit trail will be in the AUD$ table in the SYS schema.
One method other than auditing would be to read the v$segment_statistics view after one refresh and before the next refresh to see if there have been any reads. You'd have to account for any automatic statistics collection jobs also.
V$SQLAREA table has two columns which help identify the queries executed by the database.
SQL_TEXT - VARCHAR2(1000) - First thousand characters of the SQL text for the current cursor
SQL_FULLTEXT - CLOB - All characters of the SQL text for the current cursor
We can use this columns to find the queries using the said materialized views