Deadlock when creating a materialized view - oracle

I am trying to create a materialized view in oracle (with sql developer).
I have tested it on a small table and everything went ok.
Now i am doing it on a very big table, and after some hour of elaboration i get the following error:
"ORA-04020: deadlock detected while trying to lock"
Is there a way to avoid it? Or can't do much since the table is too big?

Something else in your database has an object locked that your query needs in order to be built.
To find out which object try;
SELECT vo.object_id, obj.object_name, vo.oracle_username, vo.os_user_name, vo.session_id
FROM v$locked_object vo
INNER JOIN all_objects obj
ON vo.object_id = obj.object_id
Look for objects that your materialized view will be trying to use and you should see which user has the object locked.
Go to the user and ask them to commit or rollback whatever they are doing.

Related

How is the data in DBA_TAB_COLUMNS updated?

I use Oracle 'DBA_TAB_COLUMNS' quite extensively. Just have a general question about this view - Is this view 'DBA_TAB_COLUMNS' system-generated, and therefore gets updated automatically?
The reason I'm asking is, seems that there are some columns that get added into 'DBA_TAB_COLUMNS' all of a sudden. These columns have been in my Oracle database for a long time, so I'm wondering why suddenly they got added into DBA_TAB_COLUMNS.
For example, if I have a table called TABLE_TEST and there are 2 columns in it: COL_1 and COL_2, I think these 2 columns get added into DBA_TAB_COLUMNS immediately after TABLE_TEST gets created, right? Or, is there something the DBA needs to do in order to refresh DBA_TAB_COLUMNS?
I've read the Oracle documentation about it but didn't find anything specific about this question, so could someone please advise?

can I influence the dump/export order at the h2 SCRPT command

I've a h2 schema with some tables and a view.
The view is defined by:
CREATE FORCE VIEW PUBLIC.VIEW_TEST(NAME_,STREET_) AS
SELECT
USER.NAME_,
ADDRESS.STREET_
FROM
PUBLIC.USER
LEFT OUTER JOIN PUBLIC.ADDRESS ON USER.ADDRESS_= ADDRESS.ID_
After dumping (via "SCRIPT TO ..."), within the dump file, the "CREATE FORCE VIEW PUBLIC.VIEW_TEST ..." is before the "CREATE TABLE ADDRESS ..." clause. This table is joined within the view.
The result is, that after restoring the schema (via "RUNSCRIPT FROM ...") the command "SELECT * FROM VIEW_TEST" returns a error that the referenced table "ADDRESS" is unknown:
View "PUBLIC.VIEW_TEST" is invalid: "Tabelle ""ADDRESS"" not found
Table ""ADDRESS"" not found [42102-197]"; SQL statement:
SELECT * FROM VIEW_TEST [90109-197] 90109/90109
If I drop the view and recreating it, everthing works fine, but I want to automize the dumping and restoring process.
Is there a way to set the ordering of tables and views?
What is the best way to ensure, that the view definitions are at the end of the dump?
Many thanks
No, there is no such way.
Here is a related bugreport:
https://github.com/h2database/h2database/issues/2390
If you use the persistent database you can close the connection after execution of RUNSCRIPT command (make sure that you don't use DB_CLOSE_DELAY or use the SHUTDOWN command) and re-open it. The views will be initialized properly on startup.
If you use the in-memory database, the only workaround is to recompile your views with
ALTER VIEW VIEW_TEST RECOMPILE;
ALTER VIEW otherView RECOMPILE;
.....

Does TOAD for oracle generate logs of executed SQL?

I cannot seem to find a view which I created in one of my schemas within TOAD. Lets assume I don't know the exact schema in which I've created it, is there any way where I can find all the create statements which have been executed within a period of time, lets say the last days.
Thank you in advance.
If you created the view, just query ALL the views, and order by the date in which it was created.
select * from dba_objects
where object_type = 'VIEW'
order by created desc, last_ddl_time desc
We're hitting DBA_ views to make sure we look at EVERYTHING, not just the things you have PRIVS for. Switch to ALL_ views in case you lack access, and hope you didn't create the view in a schema in which your current logon can't see.
The other way to go is query the views themselves and key in on the table you think you included in the SQL behind the view.
SELECT *
FROM dba_views
WHERE UPPER (text_vc) LIKE '%EMPLOYEES%';
You might be looking for a feature called "SQL Recall" in Toad. Press F8 or View/SQL Recall. It will show you the SQL you ran in the last month or so.

Oracle 11g Materialized View hangs

I'm attempting to create a materialized view within Oracle using a pre-built view.
create materialized view bfb_rpt_sch01.mvw_base_sales
as select * from bfb_rpt_sch01.vw_base_sales;
This command will not execute and hangs. I figured perhaps this has something to do with the view not being properly written. So I performed the following query on the view.
select count(*) from bfb_rpt_sch01.vw_base_sales
This query takes about 6 minutes to execute and returns 2.7 million. This tells me the view is not the issue, but I could be wrong.
I managed to figure out my issue. My (CREATE MATERIALIZED VIEW AS) was using a different explain compared to my (CREATE TABLE AS). If my code contained the follow line of code, it would run completely fine as (CREATE TABLE AS), but it would continue to hang for 48+ hrs before it would fail when using (CREATE MATERIALIZED VIEW AS).
WHERE a.column_name NOT IN (SELECT b.column_name FROM B) --culprit
I changed the code using the following and it now works fine.
WHERE NOT EXISTS (SELECT NULL FROM B WHERE a.column_name = b.column_name) --works
I'm not sure why this happens, perhaps bug? I don't enough about ORACLE to make the call.

Oracle - FAST REFRESH Materialized views with LEFT JOINS updates very slow

I have a Materialized view in Oracle that contains a LEFT JOIN which takes a very long time to update. When I update the underlying table it takes 63914.765 s to run (yes that is almost 17 hours).
I am using a LEFT JOIN on the same table, because I want to pivot the data from rows to columns. The pivot command is not available in this Oracle version, and using a GROUP BY + CASE is not allowed on a FAST REFRESH Materialized View.
The Materialized View Log looks like this:
CREATE MATERIALIZED VIEW LOG ON Programmes_Titles
WITH PRIMARY KEY, rowid
INCLUDING NEW Values;
The Materialized View itself looks like this (it contains 700000 rows, the Programmes_Titles table contains 900000 rows):
CREATE MATERIALIZED VIEW Mv_Web_Programmes
REFRESH FAST ON COMMIT
AS
SELECT
t1.ProgrammeId,
t1.Title as MainTitle,
t2.Title as SecondaryTitle,
--Primary key
t1.Title_Id as t1_titleId,
t2.Title_Id as t2_titleId,
t1.rowid as t1_rowid,
t2.rowid as t2_rowid
FROM
Programmes_Titles t1,
Programmes_Titles t2
WHERE
t1.Titles_Group_Type = 'mainTitle'
AND t1.Programme_Id = t2.Programme_Id(+) AND t2.Titles_Group_Type(+) = 'secondaryTitle'
The UPDATE statement I use is this:
UPDATE Programmes_Titles
SET Title = 'New title'
WHERE rowid = 'AAAL4cAAEAAAftTABB'
This UPDATE statement takes 17 hours.
When using an INNER JOIN (remove the (+)'s) it takes milliseconds.
I also tried adding INDEXES on the Mv_Web_Programmes Materialized View, but that did not seem to help either. (It still runs for more than a minute, which is way to slow, I am not waiting 17 hours after every change, so it might improved the UPDATE)
So my question is: Why does is take such a long time to UPDATE the underlying table? How can I improve this?
I've managed to reproduce your problem on a 10.2.0.3 instance. The self- and outer-join seems to be the major problem (although with indexes on every column of the MV it finally did update in under a minute).
At first I thought you could use an aggregate MV:
SQL> CREATE MATERIALIZED VIEW LOG ON Programmes_Titles
2 WITH PRIMARY KEY, ROWID (programmeId, Titles_Group_Type, title)
3 INCLUDING NEW Values;
Materialized view log created
SQL> CREATE MATERIALIZED VIEW Mv_Web_Programmes
2 REFRESH FAST ON COMMIT
3 AS
4 SELECT ProgrammeId,
5 MAX(decode(t1.Titles_Group_Type, 'mainTitle', t1.Title)) MainTl,
6 MAX(decode(t1.Titles_Group_Type, 'secondaryTitle', t1.Title)) SecTl
7 FROM Programmes_Titles t1
8 GROUP BY ProgrammeId;
Materialized view created
Unfortunately, as you have noticed, as of 10g a MV that contains MIN or MAX can only be fast-refreshed on commit after insert (so called insert-only MV). The above solution would not work for update/delete (the MV would have to be refreshed manually).
You could trace your session and open the trace file to see what SQL query gets executed so that you can find if you can optimize it via indexes.
We too faced this issue recently on Oracle 11.2.0.3
In our case, it was unavoidable to to remove an 'OUTER JOIN' due to functional impact.
On investigation, it was found that Oracle was adding a nasty HASH_SH (Hash Semi Join) hint with MV refresh DML.
Nothing worked including things mentioned in following blog-
http://www.adellera.it/blog/2010/03/11/fast-refresh-of-join-only-mvs-_mv_refresh_use_stats-and-locking-log-stats/#comment-2975
In the end, a hidden hint worked...(though in general, it should be avoided by making change in application if possible)
Oracle Doc ID 1949537.1 suggests that setting the hidden _mv_refresh_use_hash_sj parameter to FALSE should prevent it using that hint.
alter session set "_mv_refresh_use_hash_sj"=FALSE;
That stopped CBO using the HASH_SJ hint.
Posting it here in the interests of others.

Resources