Avoiding frequent call to same view inside a Oracle procedure - oracle

I have a oracle view it returns 5 million records from different tables and i use this view to insert into different tables using a single procedure, inside this procedure i use this several times and this is affecting the performance, is there any way we can query the view once and later i can use it multiple places?

A view is a stored query; itself, it doesn't contain any data. If its code is complex and fetches data from several tables, using different conditions, aggregations, whatnot, it can take some time to access data.
In your situation, maybe a global (or private; depending on Oracle version you use) temporary table (GTT) would help.
you create it once
at the beginning of the procedure, insert data from the view into it
the rest of the procedure would work with those prepared data
once the session (or transaction; depending on how you set the GTT up) is over, data from the table is lost
the table can be reused next time you run the procedure

Related

In Oracle 19c database, when we drop a table what happens to the procedures, triggers, index that uses this table?

In Oracle 19c database, when we drop a table what happens to the procedures, triggers, index that uses this table?
Will the triggers, procedures, index gets dropped automatically or
will it become INVALID status?
I want to know what is the correct process that needs to be
followed while dropping the table when you know you already have
the triggers, procedures, index associated with that particular
table?
Please help me out.
Indexes and triggers on the table will be dropped (as will grants)
Synonyms and views will become invalid
Hard-coded references to the table in procedures, packages, functions and triggers will make them invalid. References via dynamic SQL won't result in invalidation, but would fail when executed.
Query the DBA_DEPENDENCIES view to see which objects have dependencies and will get invalidated. There can be knock on impacts (dropping a table invalidates a procedure and a package that calls that procedure will be invalidated even if it doesn't reference the table directly).
If all usages are within the same user/schema, you can query USER_DEPENDENCIES instead. Don't bother with ALL_DEPENDENCIES view as, if another user has created objects referencing the victim table, you might not have privileges to see that object anyway.

What's a way I can save a trigger "template" in oracle?

Let's say I created a table test_table in development just to test a trigger, this trigger would then be reused in many other tables (future and existing).
So I code the trigger, test it, all good! But at the moment, if I want to replicate it, I will have to copy it from test_table's triggers and edit it.
So if someone deletes the table accidentally, the trigger is gone, and I don't have it saved nowhere else. Or if I just want to delete random test tables in our database, I can't.
What's a recommended way to save a trigger as a "template" in oracle? So I can reuse it in other tables and have it not be dependant of a random test table, or any table.
There are a lot of ways you can keep a copy of your TRIGGER SQLText.
Here's a few examples.
In Version Control:
You can use any of the many version control tools to maintain a versioned history for any code you like, including SQL, PL/SQL, etc. You can rewind time, view differences over time, track changes to the template, even allow concurrent development.
As a Function:
If you want the template to live in the database, you can create a FUNCTION (or PACKAGE)that takes as parameters the target USER and TABLE, and it replaces the USER and TABLE values in its template to generate the SQLTEXT required to create or replace the template TRIGGER on the target TABLE. You can make it EDITIONABLE as needed.
In a Table:
You can always just create a TABLE that holds template TRIGGER SQLText as a CLOB or VARCHAR2. It would need to be somewhere where it isn't likele to be "randomly" deleted, though. You can AUDIT changes to the TABLE's data, to see the template change over time. Oracle has tons of auditing options.
In the logs:
You can just log (all) DDL out. If you ENABLE_DDL_LOGGING, the log xml will have a copy of every DDL statement, categorized, along with when and where it came from.

How to find number of times record is accessed for oracle

I have oracle 10g database in my application. How to find out that how many times the a particular records has been accessed in particular table.
In general, to do that, you need to access records in a table though stored procedure, not through SELECT statement.
But, here is how it could be simplified:
you add a requirement that any SELECT to your table should have a function call:
select yourtable.* from yourtable
where yourfunct('yourtable', yourtable.key) = 'done'
this could be easily done through view plus revoking permissions to read the table itself
in your function, you either save table/key pair inside a table in a package (you don't need to start a transaction to do that) or you start an autonomous transaction and write into a real table.
writing into a variable in a package is not thead safe, but it is much faster.
creating a transaction is slooooooower, but it will garantie a result.
My personal preference would be to question an original task. Maybe it would be enough to create sort of 'log entry' table where requests for data are recorded.

Creating Materialized view in oracle taking forever

I have following query which has select query that returns data in 5sec. But when I add create materialized view command infront it takes ever for the query to create materialized view.
When you create a materialized view, you actually create a copy of the data that Oracle takes care to keep synchronized (and it makes those views somewhat like indexes). If your view operates over a big amount of data or over data from other servers, it's natural that the creating this view can take time.
From docs.oracle.com:
A materialized view is a replica of a target master from a single
point in time.
Just for "yuks", try
create table temp_tab nologging as select ...
I've seen cases where MV creation is long for some reason, probably logging.
Also, query development tools sometimes begin returning the data to the screen right away, but if you "paged" to the last row, you would find out how long it really takes to get all the data.
You should profile the select statement with explain plan and understand the table cardinality, indexes, waits states when running, ... in order to see if the query needs tuning.

What is the fastest way to insert data into an Oracle table?

I am writing a data conversion in PL/SQL that processes data and loads it into a table. According to the PL/SQL Profiler, one of the slowest parts of the conversion is the actual insert into the target table. The table has a single index.
To prepare the data for load, I populate a variable using the rowtype of the table, then insert it into the table like this:
insert into mytable values r_myRow;
It seems that I could gain performance by doing the following:
Turn logging off during the insert
Insert multiple records at once
Are these methods advisable? If so, what is the syntax?
It's much better to insert a few hundred rows at a time, using PL/SQL tables and FORALL to bind into insert statement. For details on this see here.
Also be careful with how you construct the PL/SQL tables. If at all possible, prefer to instead do all your transforms directly in SQL using "INSERT INTO t1 SELECT ..." as doing row-by-row operations in PL/SQL will still be slower than SQL.
In either case, you can also use direct-path inserts by using INSERT /*+APPEND*/, which basically bypasses the DB cache and directly allocates and writes new blocks to data files. This can also reduce the amount of logging, depending on how you use it. This also has some implications, so please read the fine manual first.
Finally, if you are truncating and rebuilding the table it may be worthwhile to first drop (or mark unusable) and later rebuild indexes.
Regular insert statements are the slowest way to get data in a table and not meant for bulk inserts. The following article references a lot of different techniques for improving performance: http://www.dba-oracle.com/oracle_tips_data_load.htm
Drop the index, then insert the rows, then re-create the index.
If dropping the index doesn't speed things up enough, you need the Oracle SQL*Loader:
http://www.oracle.com/technology/products/database/utilities/htdocs/sql_loader_overview.html
Suppose you have taken eid,ename,sal,job. So create a table first as:
SQL>create table tablename(eid number, ename varchar2(20),sal number,job char(10));
Now insert data:-
SQL>insert into tablename values(&eid,'&ename',&sal,'&job');
Check this link
http://www.dba-oracle.com/t_optimize_insert_sql_performance.htm
main points to consider for your
case is to use Append hint as this
will directly append into the table
instead of using freelist. If you can afford to turn off logging than use append with nologging hint to do it
Use a bulk insert instead instead of iterating in PL/SQL
Use sqlloaded to load the data directly into the table if you are getting data from a file feed
Here are my recommendations on fast insert.
Trigger - Disable any triggers associated with a table. Enable after Inserts are complete.
Index - Drop Index and re-create it after your Inserts are complete.
Stale stats - Re-analyze table and index stats.
Index de-fragmentation - Rebuild Index if needed
Use No Logging -Insert using INSERT APPEND (Oracle only). This approach is very risky approach, no redo logs are generated therefore you can’t do a rollback - make a backup of table before you start and don't try on live tables. Check if your db has similar option
Parallel Insert: Running parallel insert will get the job faster.
Use Bulk Insert
Constraints - Not much overhead during inserts but still a good idea to check, if it is still slow after even after step 1
You can learn more on http://www.dbarepublic.com/2014/04/slow-insert.html
Maybe one of your best option is to avoid Oracle as much as possible actually.
I've been baffled by this myself, but very often a Java process can outperform many of the Oracle's utilities which either use OCI (read: SQL Plus) or will take up so much of your time to get right (read: SQL*Loader).
This doesn't prevent you to use specific hints either (like /APPEND/).
I've been pleasantly surprised each time I've turned to that kind of solution.
Cheers,
Rollo

Resources