The document discusses views in Oracle databases and how they have evolved beyond simple stored SQL queries. Views can now serve as an isolation layer between applications and tables, accept DML operations directly or through triggers, and include complex functionality through features like parameterized conditions, dynamic SQL, and INSTEAD OF triggers. The document outlines techniques for optimizing DML operations on views, such as using dynamic SQL to only update changed columns, and leveraging compound triggers for shared program logic. It also warns of performance issues that can arise from logical primary keys on views.
For most developers, knowledge of PL/SQL starts from writing user-defined functions. As a result, even if this code is functionally correct, the program units are fired significantly more often than needed, impact CBO decisions, and cause execution plan degradation. This section addresses these issues and includes a number of examples of how PL/SQL can extend basic SQL functionality.
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...Michael Rosenblum
In any large ecosystem, there are always areas that stay in the twilight, outside of the public’s attention. This deep dive attempts to change the trend regarding two, at first glance, unrelated PL/SQL topics: hierarchical profiler (HProf) and database triggers. But if you look closer, there’s something in common: they’re significantly underused! HProf because nobody heard about it, database triggers because of decades-old stigma. Let’s put both of them back into our development toolset!
Part #1. One of the most critical FREE SQL and PL/SQL performance tuning tools is almost totally unknown! If you ask, how much time is spent on routine A? How often is function B called? Most developers would hand-code something instead of using the Oracle PL/SQL HProf. This isn’t because the provided functionality is disliked, but because developers aren’t aware of its existence! This presentation is an attempt to alter this trend and reintroduce HProf to a wider audience.
Part #2. There isn’t anything “evil” about database triggers; they just have to be used where they can actually solve problems. In this presentation, various kinds of triggers will be examined from a global system optimization view, including tradeoffs between multiple goals (e.g., depending upon the available hardware, developers can select either CPU-intensive or I/O-intensive solutions). This presentation will focus on the most common performance problems related to different kinds of DML triggers and the proper ways of resolving them.
This presentation is the attempt to switch sides and show code management from the developer's point of view. It stays outside of various VCS solutions and focuses on hands-on approaches: activity control via system triggers, conditional compilation, synonym manipulation, utilization of Edition-Based Redefinition (EBR).
Managing Unstructured Data: Lobs in the World of JSONMichael Rosenblum
One of the most critical aspects of building effective systems is the successful management of unstructured/semi-structured information. The database is no longer only a place to store dollars and cents for the purposes of accounting. Efficient manipulation of JSON has become one of the most critical elements of contemporary database infrastructure.
Even though you can store JSON documents in VARCHAR2 columns, in reality you will quickly outgrow VARCHAR2 size limitations and will have to switch to CLOBs for storage. However, few people in the development community really understand the underlying mechanics of Oracle LOB datatypes and consider it yet another DBA issue! This presentation attempt to fill that knowledge gap:
- Core conceptual elements of how Oracle works with LOBs (multi-segment storage, IO mechanism, copy semantics/pointer semantics, etc.)
- SecureFiles/BasicFiles implementation issues
- Best practices of LOB manipulation (both generic and JSON-related)
Overall, this presentation gives database developers sufficient knowledge to be able to build efficient modern applications. Real-life examples will be included to pinpoint key ideas and solutions.
Data Tracking: On the Hunt for Information about Your DatabaseMichael Rosenblum
Behind the scenes, Oracle databases hide a myriad of processes to ensure that your data can be safely stored and retrieved. These processes also leave “tracks” (or they COULD leave tracks if you set them up properly). These tracks, together with application-specific data, create a complete representation of the system’s day-to-day activity. Too often this representation is lost at the DBA/Developer borderline, mostly because one side is not aware of the needs of the other. This presentation strives to bridge this gap. It focuses on key sources of database information and techniques that are useful for both DBAs and developers:
- Data Dictionary
- Oracle Logging
- Oracle Tracing
- Advanced code instrumentation
The Hidden Face of Cost-Based Optimizer: PL/SQL Specific StatisticsMichael Rosenblum
Database statistics are not limited to tables, columns, and indexes. PL/SQL functions also have a number of associated statistics, namely costs (CPU, I/O, network), selectivity, and cardinality (for functions that return collections). These statistics have default values that only somewhat represent reality. However, these values are always used by Oracle's cost-based optimizer to build execution plans. This session uses real-life examples to illustrate how properly managed PL/SQL statistics can significantly improve executions plans. It also demonstrates that Oracle's extensible optimizer is flexible enough to support packaged functions.
For most developers, knowledge of PL/SQL starts from writing user-defined functions. As a result, even if this code is functionally correct, the program units are fired significantly more often than needed, impact CBO decisions, and cause execution plan degradation. This section addresses these issues and includes a number of examples of how PL/SQL can extend basic SQL functionality.
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...Michael Rosenblum
In any large ecosystem, there are always areas that stay in the twilight, outside of the public’s attention. This deep dive attempts to change the trend regarding two, at first glance, unrelated PL/SQL topics: hierarchical profiler (HProf) and database triggers. But if you look closer, there’s something in common: they’re significantly underused! HProf because nobody heard about it, database triggers because of decades-old stigma. Let’s put both of them back into our development toolset!
Part #1. One of the most critical FREE SQL and PL/SQL performance tuning tools is almost totally unknown! If you ask, how much time is spent on routine A? How often is function B called? Most developers would hand-code something instead of using the Oracle PL/SQL HProf. This isn’t because the provided functionality is disliked, but because developers aren’t aware of its existence! This presentation is an attempt to alter this trend and reintroduce HProf to a wider audience.
Part #2. There isn’t anything “evil” about database triggers; they just have to be used where they can actually solve problems. In this presentation, various kinds of triggers will be examined from a global system optimization view, including tradeoffs between multiple goals (e.g., depending upon the available hardware, developers can select either CPU-intensive or I/O-intensive solutions). This presentation will focus on the most common performance problems related to different kinds of DML triggers and the proper ways of resolving them.
This presentation is the attempt to switch sides and show code management from the developer's point of view. It stays outside of various VCS solutions and focuses on hands-on approaches: activity control via system triggers, conditional compilation, synonym manipulation, utilization of Edition-Based Redefinition (EBR).
Managing Unstructured Data: Lobs in the World of JSONMichael Rosenblum
One of the most critical aspects of building effective systems is the successful management of unstructured/semi-structured information. The database is no longer only a place to store dollars and cents for the purposes of accounting. Efficient manipulation of JSON has become one of the most critical elements of contemporary database infrastructure.
Even though you can store JSON documents in VARCHAR2 columns, in reality you will quickly outgrow VARCHAR2 size limitations and will have to switch to CLOBs for storage. However, few people in the development community really understand the underlying mechanics of Oracle LOB datatypes and consider it yet another DBA issue! This presentation attempt to fill that knowledge gap:
- Core conceptual elements of how Oracle works with LOBs (multi-segment storage, IO mechanism, copy semantics/pointer semantics, etc.)
- SecureFiles/BasicFiles implementation issues
- Best practices of LOB manipulation (both generic and JSON-related)
Overall, this presentation gives database developers sufficient knowledge to be able to build efficient modern applications. Real-life examples will be included to pinpoint key ideas and solutions.
Data Tracking: On the Hunt for Information about Your DatabaseMichael Rosenblum
Behind the scenes, Oracle databases hide a myriad of processes to ensure that your data can be safely stored and retrieved. These processes also leave “tracks” (or they COULD leave tracks if you set them up properly). These tracks, together with application-specific data, create a complete representation of the system’s day-to-day activity. Too often this representation is lost at the DBA/Developer borderline, mostly because one side is not aware of the needs of the other. This presentation strives to bridge this gap. It focuses on key sources of database information and techniques that are useful for both DBAs and developers:
- Data Dictionary
- Oracle Logging
- Oracle Tracing
- Advanced code instrumentation
The Hidden Face of Cost-Based Optimizer: PL/SQL Specific StatisticsMichael Rosenblum
Database statistics are not limited to tables, columns, and indexes. PL/SQL functions also have a number of associated statistics, namely costs (CPU, I/O, network), selectivity, and cardinality (for functions that return collections). These statistics have default values that only somewhat represent reality. However, these values are always used by Oracle's cost-based optimizer to build execution plans. This session uses real-life examples to illustrate how properly managed PL/SQL statistics can significantly improve executions plans. It also demonstrates that Oracle's extensible optimizer is flexible enough to support packaged functions.
Performance Instrumentation for PL/SQL: When, Why, HowKaren Morton
Performance instrumentation is a little extra code that developers put into their PL/SQL applications that tells everyone—owners, users, system managers, and the software developers themselves—exactly where your software is spending your time. With it, managing performance is a snap. Good instrumentation makes it so normal people, not just specialists, can diagnose and solve performance problems quickly and permanently, often before your users even sense something is wrong. However, without good time-based performance instrumentation, managing performance becomes nightmarishly complex and expensive.
With as little as two lines of code you will be able to monitor specific tasks in your application and make one of the most difficult steps of implementing response-time based problem diagnosis (Method R) into one of the easiest. In addition, these techniques will enable you to correlate database statistics back to business tasks and help discover those tasks that are heavy resource consumers. This presentation will provide examples of how to perform the instrumentation using Oracle's built-in packages and a free open source instrumentation package called the Instrumentation Library for Oracle (ILO). Its cost on every level is free, and the significant collateral benefits that can be achieved will make code instrumentation part of your coding standards.
Flexviews is a materialized view solution for MySQL. This set of slides introduces Flexviews concepts, and gives some examples in how to use it and what to use it for.
Hello Everyone ! Hope everybody doing good in their work and with their busy life.
Today i am listing down some interesting ORA- errors which i found recently as a Beginner, My Good Luck i have solved those too. So, here i am Listing down the errors with solutions.
It happens when you work with oracle, you may face or might be facing.
So, guys ! Be fearless. Have a look over it. If you need any help, Please Please let me know..
Thankyou.
This slide deck describes the Flexviews materialized view toolkit for MySQL:
http://flexvie.ws
Learn how to use incrementally refreshable materialized views, and how they can improve your performance.
Abstract: Developers - If you are not using Bulk Binds you are not writing PL/SQL efficiently!
Bulk binding has been around for a long time, yet there are sites out there that don't utilise this feature to its full extent, if at all. Every release of Oracle improves on this functionality so obviously it's a topic worthy of consistent awareness.
In PL/SQL and SQL, there are a few nifty features related to bulk binding you may not have seen - it's not all about BULK COLLECT. Whether you're on 8i, 11g or anything in between, you'll benefit from the concepts described in this seminar and become a Bulk Binding Baron!
Oracle 11g new features for developersScott Wesley
Abstract: There are a wealth of new features available in the 11g database release. This presentation touches on SQL & PL/SQL features I found of interest, and concentrates particularly on virtual columns.
Relevant scripts found at my blog
http://grassroots-oracle.com/2009/07/presentations.html#11gNewFeatures
Performance Instrumentation for PL/SQL: When, Why, HowKaren Morton
Performance instrumentation is a little extra code that developers put into their PL/SQL applications that tells everyone—owners, users, system managers, and the software developers themselves—exactly where your software is spending your time. With it, managing performance is a snap. Good instrumentation makes it so normal people, not just specialists, can diagnose and solve performance problems quickly and permanently, often before your users even sense something is wrong. However, without good time-based performance instrumentation, managing performance becomes nightmarishly complex and expensive.
With as little as two lines of code you will be able to monitor specific tasks in your application and make one of the most difficult steps of implementing response-time based problem diagnosis (Method R) into one of the easiest. In addition, these techniques will enable you to correlate database statistics back to business tasks and help discover those tasks that are heavy resource consumers. This presentation will provide examples of how to perform the instrumentation using Oracle's built-in packages and a free open source instrumentation package called the Instrumentation Library for Oracle (ILO). Its cost on every level is free, and the significant collateral benefits that can be achieved will make code instrumentation part of your coding standards.
Flexviews is a materialized view solution for MySQL. This set of slides introduces Flexviews concepts, and gives some examples in how to use it and what to use it for.
Hello Everyone ! Hope everybody doing good in their work and with their busy life.
Today i am listing down some interesting ORA- errors which i found recently as a Beginner, My Good Luck i have solved those too. So, here i am Listing down the errors with solutions.
It happens when you work with oracle, you may face or might be facing.
So, guys ! Be fearless. Have a look over it. If you need any help, Please Please let me know..
Thankyou.
This slide deck describes the Flexviews materialized view toolkit for MySQL:
http://flexvie.ws
Learn how to use incrementally refreshable materialized views, and how they can improve your performance.
Abstract: Developers - If you are not using Bulk Binds you are not writing PL/SQL efficiently!
Bulk binding has been around for a long time, yet there are sites out there that don't utilise this feature to its full extent, if at all. Every release of Oracle improves on this functionality so obviously it's a topic worthy of consistent awareness.
In PL/SQL and SQL, there are a few nifty features related to bulk binding you may not have seen - it's not all about BULK COLLECT. Whether you're on 8i, 11g or anything in between, you'll benefit from the concepts described in this seminar and become a Bulk Binding Baron!
Oracle 11g new features for developersScott Wesley
Abstract: There are a wealth of new features available in the 11g database release. This presentation touches on SQL & PL/SQL features I found of interest, and concentrates particularly on virtual columns.
Relevant scripts found at my blog
http://grassroots-oracle.com/2009/07/presentations.html#11gNewFeatures
Abstract: Oracle released a feature in 10g Release 2 they thought worthy of facilitating in previous versions via patch sets - so I thought it was worthy enough for a closer look.
Conditional compilation isn't a foreign concept in the programming world, and for the developer aficionado it's a wonderful paradigm to explore.
Conditional compilation was designed with the main intention of being able to create database version specific code. With the recent advent of 11g, developers can actually start adding 11g features to their 10g code today!
However it provides the savvy PL/SQL developer to enhance their code in more ways than just gearing up for the next release… Dust of your software engineering hats and discover how to utilise conditional compilation to explore concepts such as latent self tracing code; latent assertions; and enhanced prototyping for your unit tests.
This seminar will illustrate several examples of conditional compilation that will open your mind; ultimately benefit your users; and can be implemented as far back as 9.2!
Over the years there have been countless technical and social presentations doting on 5, 10, 12 ways to improve this, that and the other.
I will go through various performance tweaks (not tweets) for Oracle Application Express without limiting myself to a golden number.
These improvements will vary from simple PL/SQL refactoring; to monitoring for bottlenecks in your application; to cutting down maintenance time - which relates to the performance of you as an Oracle developer with only 24 hours in a day.
We may even visit a little APEX instrumentation on the way.
In the beginning, when the cost based optimizer was new, developers soon learnt they needed to code correctly to avoid performance problems. As the CBO developed, we relaxed and assumed that it would handle everything for us. As a result coding practices which prevent good performance are appearing again. The arrival of the Java Developer to whom the database is just a data store, and the fact that we are storing much more data has contributed to the issue as well.
This presentation will identify some commonly found coding mistakes that cause performance problems and look at how to resolve them.
Have you ever wondered how search works while visiting an e-commerce site, internal website, or searching through other types of online resources? Look no further than this informative session on the ways that taxonomies help end-users navigate the internet! Hear from taxonomists and other information professionals who have first-hand experience creating and working with taxonomies that aid in navigation, search, and discovery across a range of disciplines.
This presentation, created by Syed Faiz ul Hassan, explores the profound influence of media on public perception and behavior. It delves into the evolution of media from oral traditions to modern digital and social media platforms. Key topics include the role of media in information propagation, socialization, crisis awareness, globalization, and education. The presentation also examines media influence through agenda setting, propaganda, and manipulative techniques used by advertisers and marketers. Furthermore, it highlights the impact of surveillance enabled by media technologies on personal behavior and preferences. Through this comprehensive overview, the presentation aims to shed light on how media shapes collective consciousness and public opinion.
Sharpen existing tools or get a new toolbox? Contemporary cluster initiatives...Orkestra
UIIN Conference, Madrid, 27-29 May 2024
James Wilson, Orkestra and Deusto Business School
Emily Wise, Lund University
Madeline Smith, The Glasgow School of Art
0x01 - Newton's Third Law: Static vs. Dynamic AbusersOWASP Beja
f you offer a service on the web, odds are that someone will abuse it. Be it an API, a SaaS, a PaaS, or even a static website, someone somewhere will try to figure out a way to use it to their own needs. In this talk we'll compare measures that are effective against static attackers and how to battle a dynamic attacker who adapts to your counter-measures.
About the Speaker
===============
Diogo Sousa, Engineering Manager @ Canonical
An opinionated individual with an interest in cryptography and its intersection with secure software development.
This presentation by Morris Kleiner (University of Minnesota), was made during the discussion “Competition and Regulation in Professions and Occupations” held at the Working Party No. 2 on Competition and Regulation on 10 June 2024. More papers and presentations on the topic can be found out at oe.cd/crps.
This presentation was uploaded with the author’s consent.
Acorn Recovery: Restore IT infra within minutesIP ServerOne
Introducing Acorn Recovery as a Service, a simple, fast, and secure managed disaster recovery (DRaaS) by IP ServerOne. A DR solution that helps restore your IT infra within minutes.
1. 1 of 90
#458: A New View of Database
Views
Michael Rosenblum
Dulcian, Inc.
www.dulcian.com
2. 2 of 90
Who Am I? – “Misha”
Oracle ACE
Co-author of 3 books
PL/SQL for Dummies
Expert PL/SQL Practices
Oracle PL/SQL Performance Tuning Tips & Techniques
(Rosenblum & Dorsey, Oracle Press, July 2014)
Won ODTUG 2009 Speaker of the Year
Known for:
SQL and PL/SQL tuning
Complex functionality
Code generators
Repository-based development
3. 3 of 90
Views???
Common train of thought:
Stored SQL queries
Nothing to worry about
Reasonably transparent and stackable
Minimal impact
Have been around forever…..
(Usually implies)…and have never changed.
4. 4 of 90
Views!!!
“Thick database” approach:
Views can serve as an isolation layer
UI should never talk to tables!
Views can be easily changed.
Views are editionable (EBR).
Isolation can be bi-directional.
Views are complex.
Lots of new functionality in every version
Can impact Cost Based Optimizer (CBO) decisions
Side-effects and non-trivial impact
5. 5 of 90
Outline
To be discussed:
De-normalized views with INSTEAD OF triggers
Function-based views
Special cases:
Compound triggers
Cross-edition views
Various performance considerations
Will not be discussed:
Object views
Materialized views
7. 7 of 90
The Idea
View is (IMHO!):
Data set, broadly defined at design-time and formed
at run-time.
The definition may mutate via:
Parameterized conditions
Dynamic SQL
This data set may accept DMLs
Only on a per-row basis (no statement-level actions)
Directly or via associated PL/SQL program units
Set is not persistent and may need to be rebuilt to accept
DMLs.
8. 8 of 90
The Reasoning
Logical denormalization is great:
Less coding in the UI
Transparent system design
Long-term protection against data model changes
Simplified testing
10. 10 of 90
create or replace view scott.v_emp
as
select e.empno,
e.ename,
e.deptno,
d.dname,
e.sal
from scott.emp e,
scott.dept d
where e.deptno=d.deptno
Basic Code
11. 11 of 90
select *
from dba_updatable_columns
where table_name = 'V_EMP'
COLUMN_NAME UPDATABLE INSERTABLE DELETABLE
--------------- --------------- ------------- ---------
EMPNO YES YES YES
ENAME YES YES YES
DEPTNO YES YES YES
DNAME NO NO NO
SAL YES YES YES
Direct DML…Sometimes
12. 12 of 90
create or replace trigger scott.v_emp_iu
instead of update on scott.v_emp
begin
if :new.sal!=:old.sal then
if sys_context ('userenv','CLIENT_INFO')='SalMaint'
then
update emp
set sal = :new.sal
where empno = :old.empno;
else
raise_application_error
(-20001,'Not enough privileges');
end if;
else
update emp
set ename = :new.ename
where empno = :old.empno;
end if;
end;
INSTEAD-OF – Functionality
13. 13 of 90
exec scott.runStats_pkg.rs_start;
alter trigger scott.v_emp_iu disable;
begin
for i in 1..10000 loop
update scott.v_emp set ename=ename where empno = 7782;
end loop;
end;
/
exec scott.runStats_pkg.rs_middle;
alter trigger scott.v_emp_iu enable;
begin
for i in 1..10000 loop
update scott.v_emp set ename=ename where empno = 7782;
end loop;
end;
/
exec scott.runStats_pkg.rs_stop;
Run1 ran in 35 cpu hsecs
Run2 ran in 77 cpu hsecs
run 1 ran in 45.45% of the time
Name Run1 Run2 Diff
STAT...CPU used by this session 36 79 43
STAT...execute count 10,037 20,036 9,999
STAT...session logical reads 40,441 50,480 10,039
INSTEAD-OF – Extra Cost
What???
15. 15 of 90
DML Implementation
UPDATE on view = SELECT + UPDATE
DELETE on view = SELECT + DELETE
INSERT on view = Only INSERT
16. 16 of 90
Test Case (1)
CREATE TYPE test_tab_ot AS OBJECT (owner_tx VARCHAR2(30),
name_tx VARCHAR2(30),
object_id NUMBER,
type_tx VARCHAR2(30));
CREATE TYPE test_tab_nt IS TABLE OF test_tab_ot;
CREATE FUNCTION f_searchTestTab_tt (i_type_tx VARCHAR2) RETURN test_tab_nt
IS
v_out_tt test_tab_nt;
begin
SELECT test_tab_ot(owner, object_name, object_id, object_type)
BULK COLLECT INTO v_out_tt
FROM test_tab
WHERE object_type = i_type_tx;
dbms_output.put_line('Inside f_searchTestTab_tt:'||v_out_tt.count);
RETURN v_out_tt;
END;
17. 17 of 90
Test Case (2)
create or replace view v_search_table as
select *
from table(f_searchtesttab_tt('TABLE'));
create or replace trigger v_search_table_iiud
instead of insert or update or delete on v_search_table
begin
if inserting then
dbms_output.put_line('Insert');
elsif updating then
dbms_output.put_line('Update');
elsif deleting then
dbms_output.put_line(‘Delete');
end if;
end;
18. 18 of 90
DML Check
SQL> INSERT INTO v_search_table (object_id, name_tx)
2 VALUES (-1,'A');
Insert
1 row created.
SQL> UPDATE v_search_table SET name_tx = 'Test‘
2 WHERE object_id = 5;
Inside f_searchTestTab_tt:1571
Update
1 row updated.
SQL> DELETE FROM v_search_table WHERE object_id = 5;
Inside f_searchTestTab_tt:1571
Delete
1 row deleted.
Function is not fired!
Process all to update one?
19. 19 of 90
Important!
To fire INSTEAD OF UPDATE/DELETE,
Oracle must locate row first.
Oracle must have the whole resulting set
available to filter it
… but you can cheat
20. 20 of 90
Parameterized View (1)
CREATE PACKAGE global_pkg IS
v_object_id NUMBER;
END;
CREATE FUNCTION f_searchTestTab_tt (i_type_tx varchar2) RETURN
test_tab_nt is
v_out_tt test_tab_nt;
BEGIN
IF global_pkg.v_object_id IS NULL THEN
SELECT test_tab_ot(owner, object_name, object_id, object_type)
BULK COLLECT INTO v_out_tt
FROM test_tab
WHERE object_type = i_type_tx;
ELSE
SELECT test_tab_ot(owner, object_name, object_id, object_type)
BULK COLLECT INTO v_out_tt
FROM test_tab
WHERE object_id = global_pkg.v_object_id;
END IF;
dbms_output.put_line
('Inside f_searchTestTab_tt:'||v_out_tt.count);
RETURN v_out_tt;
END;
Usage (if needed)
Global parameter
21. 21 of 90
Parameterized View (2)
SQL> BEGIN global_pkg.v_object_id:=5; END;
2 /
SQL> UPDATE v_search_table SET name_tx = 'Test'
2 WHERE object_id = 5;
Inside f_searchTestTab_tt:1
Update
1 row updated.
SQL> DELETE FROM v_search_table WHERE object_id = 5;
Inside f_searchTestTab_tt:1
Delete
1 row deleted.
22. 22 of 90
Parameterized View (3)
SQL> exec runstats_pkg.rs_start;
SQL> BEGIN
2 global_pkg.v_object_id:=NULL;
3 FOR i IN 1..100 LOOP
4 UPDATE v_search_table SET name_tx = 'Test'||i
5 WHERE object_id = 5;
6 END LOOP;
7 END;
8 /
SQL> exec runstats_pkg.rs_middle;
SQL> BEGIN
2 global_pkg.v_object_id:=5;
3 FOR i IN 1..100 LOOP
4 UPDATE v_search_table SET name_tx = 'Test'||i
5 WHERE object_id = 5;
6 END LOOP;
7 END;
8 /
SQL> exec runstats_pkg.rs_stop;
Run1 ran in 181 cpu hsecs
Run2 ran in 28 cpu hsecs
run 1 ran in 646.43% of the time
5x improvement
24. 24 of 90
Alternative to INSTEAD OF
You can also create a COMPOUND trigger
instead of an INSTEAD OF trigger
Trigger with common program area
Impact
Pro:
Common program area – possible to share code and
global variables simulating statement-level BEFORE
event (sorry, there is no way to simulate an AFTER event)
Con:
Not very stable in 11g
25. 25 of 90
CREATE OR REPLACE PACKAGE counter_pkg IS
v_nr NUMBER:=0;
PROCEDURE p_check;
procedure p_up;
END;
CREATE OR REPLACE PACKAGE BODY counter_pkg IS
PROCEDURE p_check is
BEGIN
dbms_output.put_line('Fired:'||counter_pkg.v_nr);
counter_pkg.v_nr:=0;
END;
procedure p_up is
begin
counter_pkg.v_nr:=counter_pkg.v_nr+1;
end;
END;
create or replace function f_securityCheck_yn return varchar2 is
begin
counter_pkg.p_up;
if sys_context ('USERENV', 'CLIENT_INFO') ='SalMaint' then
return 'Y';
else
return 'N';
end if;
end;
create function f_change_nr (i_nr number) return number is
begin
counter_pkg.p_up;
return i_nr+1;
end;
Monitoring tool
26. 26 of 90
CREATE OR REPLACE TRIGGER v_search_table_IIUD
INSTEAD OF INSERT OR UPDATE OR DELETE ON v_search_table
BEGIN
if f_securityCheck_yn = 'Y' then
IF INSERTING THEN dbms_output.put_line('Insert');
ELSIF UPDATING THEN dbms_output.put_line('Update');
ELSIF DELETING THEN dbms_output.put_line('Delete');
END IF;
end if;
END;
create or replace trigger v_search_table_IIUD_comp
for insert or update or delete on v_search_table
COMPOUND TRIGGER
v_check_yn varchar2(1);
instead of each row is
begin
if v_check_yn is null then
v_check_yn:=f_securityCheck_yn;
end if;
if v_check_yn = 'Y' then
IF INSERTING THEN dbms_output.put_line('Insert');
ELSIF UPDATING THEN dbms_output.put_line('Update');
ELSIF DELETING THEN dbms_output.put_line('Delete');
END IF;
end if;
end instead of each row;
end;
Performance impact (1)
Common area
27. 27 of 90
SQL> alter trigger v_search_table_IIUD_COMP disable;
SQL> alter trigger v_search_table_IIUD enable;
SQL> update v_search_table set name_tx = 'Test';
Inside f_searchTestTab_tt:1571
1571 rows updated.
SQL> exec counter_pkg.p_check;
Fired:1571
SQL> alter trigger v_search_table_IIUD_COMP enable;
SQL> alter trigger v_search_table_IIUD disable;
SQL> update v_search_table set name_tx = 'Test';
Inside f_searchTestTab_tt:1571
1571 rows updated.
SQL> exec counter_pkg.p_check;
Fired:1
SQL> exec dbms_application_info.set_client_info('SalMaint');
SQL> update v_search_table set name_tx = 'Test';
Inside f_searchTestTab_tt:1571
Update
Update
....
1571 rows updated.
SQL> exec counter_pkg.p_check;
Fired:1
Performance impact (2)
Only one call!
29. 29 of 90
The Real Story
Synthetic primary keys on views
Sometimes required by front-end environments (to
uniquely identify the row in the cache)
Extremely dangerous if blindly used for
INSERT/UPDATE/DELETE
30. 30 of 90
Test Case
CREATE OR REPLACE VIEW v_test_tab AS
SELECT 'Main|'||object_id pk_tx,
a.*
FROM test_tab_main a
UNION ALL
SELECT 'Other|'||object_id pk_tx,
a.*
FROM test_tab_other a;
33. 33 of 90
Resource Issues
Problem
INSTEAD-OF UPDATE triggers often reference all
columns of the underlying tables
… instead of trying to figure out what has been changed.
UNDO is generated for all columns mentioned in
the UPDATE statement
… regardless of whether they were changed or not
… which causes major I/O overhead.
Alternative:
Use Dynamic SQL to modify only changed columns
… i.e. trade CPU utilization for better I/O!
34. 34 of 90
Regular Trigger
create or replace trigger v_test_tab_iu
instead of update on v_test_tab
begin
if :new.object_type=‘TABLE' then
update test_tab_main
set owner=:new.owner, object_name=:new.object_name,
subobject_name=:new.subobject_name,
object_type=:new.object_type,
created=:new.created, last_ddl_time=:new.last_ddl_time,
timestamp=:new.timestamp, status=:new.status,
temporary=:new.temporary, generated=:new.generated,
secondary=:new.secondary, namespace=:new.namespace,
edition_name=:new.edition_name, sharing=:new.sharing,
editionable=:new.editionable,
oracle_maintained=:new.oracle_maintained
where object_id=:old.object_id;
else
update test_tab_other
set << the same list of columns as above >>
where object_id=:old.object_id;
end if;
end;
35. 35 of 90
Dynamic SQL Trigger (1)
create or replace trigger v_test_tab_dynamic_iu
instead of update on v_test_tab
declare
v_main_rec test_tab_main%rowtype;
v_mainupdate_tx varchar2(32767);
v_other_rec test_tab_other%rowtype;
v_otherupdate_tx varchar2(32767);
begin
if :new.object_type='table' then
-- compare old/new for each attribute
if :old.object_name is null and :new.object_name is not null
or :old.object_name is not null and :new.object_name is null
or :old.object_name!=:new.object_name then
v_main_rec.object_name:=:new.object_name;
v_mainupdate_tx:=v_mainupdate_tx||
case
when v_mainupdate_tx is not null then ','
else null
end||chr(10)||
' object_name=v_rec.object_name';
end if;
...
Store new value
(if changed)
36. 36 of 90
Dynamic SQL Trigger (2)
v_main_rec.object_id:=:old.object_id;
v_mainupdate_tx:=
'declare '||chr(10)||
' v_rec test_tab_main%rowtype:=:1;'||chr(10)||
'begin '||chr(10)||
' update test_tab_main ' ||chr(10)||
' set '||v_mainupdate_tx||chr(10)||
' where object_id=v_rec.object_id;'||chr(10)||
'end;';
execute immediate v_mainupdate_tx using v_main_rec;
else
<< the same logic as above for test_tab_other >>
end if;
end;
37. 37 of 90
Performance Tradeoff
SQL> exec runstats_pkg.rs_start;
<< enable Dynamic trigger>>
SQL> begin 2 for i in 1..10000 loop
3 UPDATE v_test_tab SET object_name='Test'||i WHERE object_id = 5;
4 end loop;
5 END;
6 /
SQL> exec runstats_pkg.rs_middle;
<< enable regular trigger and rerun the same logic>>
SQL> exec runstats_pkg.rs_stop;
Run1 ran in 390 cpu hsecs
Run2 ran in 496 cpu hsecs
run 1 ran in 78.63% of the time
Name Run1 Run2 Diff
STAT...recursive calls 20,329 30,244 9,915
STAT...execute count 20,102 30,095 9,993
STAT...undo change vector size 2,495,476 938,552 -1,556,924
STAT...redo size 5,820,096 2,772,332 -3,047,764
Run1 latches total versus runs -- difference and pct
Run1 Run2 Diff Pct
136,486 184,679 48,193 73.90%
More CPU time
Much less I/O
39. 39 of 90
Setup
Functions can be used as columns in views:
CREATE FUNCTION f_isEastCoast_yn (i_deptno NUMBER)
RETURN VARCHAR2
IS
v_out_yn varchar2(1);
BEGIN
SELECT CASE WHEN loc IN ('NEW YORK', 'BOSTON') THEN 'Y'
ELSE 'N'
END
INTO v_out_yn
FROM dept
WHERE deptno = i_deptno;
RETURN v_out_yn;
END;
CREATE VIEW v_emp_loc
AS
SELECT emp.empno, emp.ename, emp.deptno,
f_isEastCoast_yn(deptno) eastCoast_yn
FROM emp;
Returns Y/N
40. 40 of 90
Problem
Default behavior:
SQL> SELECT column_name, data_type, data_length
2 FROM user_tab_columns
3 WHERE table_name = 'V_EMP_LOC'
4 ORDER by column_id;
COLUMN_NAME DATA_TYPE DATA_LENGTH
--------------- --------------- -----------
EMPNO NUMBER 22
ENAME VARCHAR2 10
DEPTNO NUMBER 22
EASTCOAST_YN VARCHAR2 4000
Over-allocation can impact front-end and middle-tier
that may read the Oracle Data Dictionary.
In the case of materialized views – storage over-allocation
41. 41 of 90
Solution
CREATE OR REPLACE VIEW v_emp_loc AS
SELECT emp.empno, emp.ename, emp.deptno,
cast(f_isEastCoast_yn(deptno) as VARCHAR2(1)) eastCoast_yn
FROM emp
SQL> SELECT column_name, data_type, data_length
2 FROM user_tab_columns
3 WHERE table_name = 'V_EMP_LOC'
4 ORDER by column_id;
COLUMN_NAME DATA_TYPE DATA_LENGTH
--------------- --------------- -----------
EMPNO NUMBER 22
ENAME VARCHAR2 10
DEPTNO NUMBER 22
EASTCOAST_YN VARCHAR2 1
Exact allocation
43. 43 of 90
SELECT and ORDER BY (1)
Output:
SQL> SELECT empno, ename, f_change_nr(empno) change_nr
2 FROM emp WHERE deptno = 20
3 ORDER BY 3;
5 rows selected.
SQL> exec counter_pkg.p_check;
Fired: ?
SQL> SELECT empno, change_nr
2 FROM (SELECT empno, ename, f_change_nr(empno) change
3 FROM emp WHERE deptno = 20
4 ORDER BY 3);
5 rows selected.
SQL> exec counter_pkg.p_check;
Fired: ?
In-line view causes
double-firing
5
10
Problem:
Why does the inline view cause a double fire?
44. 44 of 90
SELECT and ORDER BY (2)
Research of 10053 trace:
Order-by elimination (OBYE)
***************************
OBYE: OBYE performed.
OBYE: OBYE bypassed: no order by to eliminate.
Final query after transformations:*** UNPARSED QUERY IS ***
SELECT "EMP"."EMPNO" "EMPNO","EMP"."ENAME" "ENAME",
"SCOTT"."F_CHANGE_NR"("EMP"."EMPNO") "CHANGE_NR"
FROM "SCOTT"."EMP" "EMP"
WHERE "EMP"."DEPTNO"=20
ORDER BY "SCOTT"."F_CHANGE_NR"("EMP"."EMPNO")
Explanation:
ORDER BY elimination is fired before the query
transformation.
It does not find an ORDER BY clause in the root SELECT
and stops.
After query transformation, ORDER BY suddenly appears.
It is not removed now.
45. 45 of 90
SELECT and ORDER BY (3)
/*+ NO_MERGE */ hint solves the problem:
SQL> select empno, change_nr
2 from (select /*+ no_merge */
3 empno, ename, f_change_nr(empno) change_nr
4 from emp where deptno = 20 order by 3);
5 rows selected.
SQL> exec counter_pkg.p_check;
Fired: ?
Why bother? Because of real views:
SQL> create or replace view v_emp as
2 select empno, ename, f_change_nr(empno) change_nr
3 from emp where deptno = 20
4 order by 3;
view created.
SQL> select empno, change_nr from v_emp;
5 rows selected.
SQL> exec counter_pkg.p_check;
Fired: ?
Query rewrite is skipped.
ORDER BY elimination
is applied directly.
Same effect
as in-line view
5
10
46. 46 of 90
Important!
ORDER BY clauses in views should be used
very cautiously and preferably avoided
altogether
… because the CBO is still not magic.
48. 48 of 90
Problem
Yes, there are cases when hints are needed.
Hints are easy to add if you have a single-level
query.
If you are using views:
Straightforward if you are lucky and can change
underlying views.
Doable otherwise, but may be tricky.
49. 49 of 90
Solution #1
Explicit naming of SELECT statements (20 char limit):
create or replace view scott.v_emp
as
select /*+ QB_NAME(V_EMP_Main) */
e.empno,
e.ename,
e.deptno,
d.dname,
e.sal
from scott.emp e,
scott.dept d
where e.deptno=d.deptno
50. 50 of 90
Solution #1 - Proof
SQL> select /*+ FULL(@V_EMP_Main e) */ *
2 from v_emp
3 where empno=7369;
EMPNO ENAME DEPTNO DNAME SAL
---------- ---------- ---------- -------------- ----------
7369 SMITH 20 RESEARCH 800
Execution Plan
----------------------------------------------------------
Plan hash value: 3625962092
----------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
----------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 30 |
| 1 | NESTED LOOPS | | 1 | 30 |
| 2 | NESTED LOOPS | | 1 | 30 |
|* 3 | TABLE ACCESS FULL | EMP | 1 | 17 |
|* 4 | INDEX UNIQUE SCAN | PK_DEPT | 1 | |
| 5 | TABLE ACCESS BY INDEX ROWID| DEPT | 1 | 13 |
----------------------------------------------------------------
51. 51 of 90
Solution #2
Find Oracle-generated object alias:
SQL> explain plan for select * from v_emp where empno=7369;
Explained.
SQL> select * from table(dbms_xplan.display(null,null,'All'));
----------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
----------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 30 |
| 1 | NESTED LOOPS | | 1 | 30 |
| 2 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 17 |
|* 3 | INDEX UNIQUE SCAN | PK_EMP | 1 | |
| 4 | TABLE ACCESS BY INDEX ROWID| DEPT | 1 | 13 |
|* 5 | INDEX UNIQUE SCAN | PK_DEPT | 1 | |
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$F5BB74E1
2 - SEL$F5BB74E1 / E@SEL$2
3 - SEL$F5BB74E1 / E@SEL$2
4 - SEL$F5BB74E1 / D@SEL$2
5 - SEL$F5BB74E1 / D@SEL$2
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("E"."EMPNO"=7369)
5 - access("E"."DEPTNO"="D"."DEPTNO")
52. 52 of 90
Solution #2 - Proof
SQL> select /*+ FULL(@SEL$2 e) */ *
2 from v_emp
3 where empno=7369;
EMPNO ENAME DEPTNO DNAME SAL
---------- ---------- ---------- -------------- ----------
7369 SMITH 20 RESEARCH 800
Execution Plan
----------------------------------------------------------
Plan hash value: 3625962092
----------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
----------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 30 |
| 1 | NESTED LOOPS | | 1 | 30 |
| 2 | NESTED LOOPS | | 1 | 30 |
|* 3 | TABLE ACCESS FULL | EMP | 1 | 17 |
|* 4 | INDEX UNIQUE SCAN | PK_DEPT | 1 | |
| 5 | TABLE ACCESS BY INDEX ROWID| DEPT | 1 | 13 |
----------------------------------------------------------------
53. 53 of 90
Keep in mind…
Naming all subqueries costs you nothing, but
makes production support much easier.
Warnings:
Names may be ignored:
If two or more query blocks have the same name
If the same query block is hinted twice with different
name
Beware of query transformation!
55. 55 of 90
Concept
Editioning view (Edition-Based Redefition):
Can be created only for edition-enabled users
Can have multiple versions
Lots of restrictions (no joins, conditions, grouping
etc.) ~ more or less a synonym to the table
-- Parent Edition
create or replace editioning view scott.v_emp_ed
as select empno, ename, hiredate from scott.emp;
-- Child Edition (new column TIMESTAMP instead of DATE)
create or replace editioning view scott.v_emp_ed
as select empno, ename, hiredate_ts from scott.emp;
56. 56 of 90
New Functionality
Editioning views may have the same triggers as tables
-- Child edition: only new data
create or replace trigger v_emp_ed_bu
before update on v_emp_ed for each row
Begin
if :new.hiredate_ts <= to_timestamp('20150101','YYYYMMDD')
then
raise_application_error(-20001,'Data is too old');
end if;
end;
-- Parent edition: only old data
create or replace trigger v_emp_ed_bu
before update on v_emp_ed for each row
Begin
if :new.hiredate > to_date('20150101','YYYYMMDD')
then
raise_application_error(-20001,'Data is too new');
end if;
end;
58. 58 of 90
Views
Multiple triggers of the same type:
FOLLOWS <trigger> clause
Triggers can be created in DISABLED state.
Create invalid view (for later recompilation):
FORCE clause
59. 59 of 90
Views with Constraints (1)
Making view non-updatable
WITH READ ONLY clause
create or replace view scott.v_emp as
select e.empno,e.ename, e.deptno, d.dname, e.sal
from scott.emp e,
scott.dept d
where e.deptno=d.deptno
with read only constraint V_EMP_RO
SQL> select constraint_name, constraint_type, table_name
2 from user_constraints
3 where table_name = 'V_EMP';
CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME
----------------- --------------- ---------------------
V_EMP_RO O V_EMP
60. 60 of 90
Views with Constraints (2)
WITH CHECK OPTION clause ~ Check constraint
Insert/Update for single-table views
Update is validated for multi-table views
Insert causes “ORA-01733: virtual column not allowed here”
Delete blocked if you have self-join
create or replace view scott.v_emp as
select e.empno, e.ename, e.deptno, d.dname, e.sal
from scott.emp e,
scott.dept d
where e.deptno=d.deptno
and d.deptno !=30
with check option constraint V_EMP_C
SQL> select constraint_name, constraint_type, table_name
2 from user_constraints
3 where table_name = 'V_EMP';
CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME SEARCH_CONDITION
----------------- --------------- ---------- ----------------
V_EMP_C V V_EMP NULL
You cannot see
condition
61. 61 of 90
Views with Constraints (3)
Primary/Unique key – documentation/CBO only
create or replace view scott.v_emp (
empno,
ename,
deptno,
dname,
sal,
constraint v_emp_pk
primary key(empno) rely disable novalidate,
constraint v_emp_uk
unique (ename) rely disable novalidate
) as
select e.empno, e.ename, e.deptno, d.dname, e.sal
from scott.emp e,
scott.dept d
where e.deptno=d.deptno
62. 62 of 90
SQL Text Expansion (1)
Problem:
Views can be based on views that can be based on
views …
How can you read what is really accessed?
Solution (12c-only)
DBMS_UTILITY.EXPAND_SQL_TEXT
63. 63 of 90
SQL Text Expansion (2)
SQL> declare
2 v_tx varchar2(32767);
3 begin
4 dbms_utility.expand_sql_text
5 ('select * from scott.v_emp', v_tx);
6 dbms_output.put_line(v_tx);
7 end;
8 /
SELECT "A1"."EMPNO" "EMPNO","A1"."ENAME"
"ENAME","A1"."DEPTNO" "DEPTNO","A1"."DNAME"
"DNAME","A1"."SAL" "SAL" FROM (SELECT "A3"."EMPNO"
"EMPNO","A3"."ENAME" "ENAME","A3"."DEPTNO"
"DEPTNO","A2"."DNAME" "DNAME","A3"."SAL" "SAL" FROM
"SCOTT"."EMP" "A3","SCOTT"."DEPT" "A2" WHERE
"A3"."DEPTNO"="A2"."DEPTNO" AND "A3"."EMPNO"<>30) "A1"
67. 67 of 90
How to Talk to Front-End
Developers
Problem:
How to explain the importance of views to front-end
developers?
Solution:
Explain the idea of roundtrip minimization!
68. 68 of 90
Practical Aspects (1)
Existing implementations:
Multiple separate requests to populate the screen
Total number of roundtrips sometimes in thousands
for a single screen
Each request is cheap.
Total cost on all levels (DB/network/app server) is huge.
69. 69 of 90
Web Application Architecture
3. Application
Server
2. Send data from
Client to app server
5. Database
6. Return Data from
database to app server
1. Client
4. Send data from
app server to database
7. Data in
Application Server
8. Return data from
app server to client
9. Data in
client
70. 70 of 90
Practical Aspects (2)
Alternative:
A view where 1 row gets all data to populate one
screen 1 round-trip
Since not a lot of data is being returned, the complexity of
such a view can be pretty high.
Very often, you trade off higher memory utilization for
less network requests.
71. 71 of 90
Web Application
Architecture
3. Application
Server
2. Send data from
Client to app server
5. Database
6. Return Data from
DB to app server
1. Client
4. Send data from
app server to DB
7. Data in
Application Server
8. Return data from
app server to client
9. Data in
client
Data
UI views
73. 73 of 90
History
Existing system:
Major part of the solution requires data transformation
via global temporary tables (session-level)
Significant scaling (from 150 to 2500 users)
Impact:
Numerous log file switches significant
performance impact
LogMiner shows that ~ 75% of DMLs are related to
GTT!
74. 74 of 90
New Knowledge
Session-level GTTs are subject to transaction
activities Even though there is no
COMMIT, there is a ROLLBACK:
INSERT
Very little UNDO is generated: It is enough to generate
the DELETE entry using ROWID as a unique identifier.
UPDATE
As it does for the actual table, Oracle needs to preserve
the pre-DML state of the row.
DELETE
The entire row should be preserved to be restored if
needed.
75. 75 of 90
Solution (1)
Views based on package variables require:
Object collection
Package to store
Very non-trivial triggers
CREATE TYPE dept_gtt_ot IS OBJECT
(deptno NUMBER,
dname VARCHAR2(14),
loc VARCHAR2(13))
/
CREATE TYPE dept_gtt_nt IS TABLE OF dept_gtt_ot
/
76. 76 of 90
CREATE OR REPLACE PACKAGE dept_gtt_pkg IS
TYPE pk_tt IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;
v_pk_tt pk_tt;
v_dept_tt dept_gtt_nt:=dept_gtt_nt();
FUNCTION f_getDept_tt RETURN dept_gtt_nt;
END;
/
CREATE OR REPLACE PACKAGE BODY dept_gtt_pkg IS
FUNCTION f_getDept_tt RETURN dept_gtt_nt IS
BEGIN
RETURN v_dept_tt;
END;
END;
/
CREATE OR REPLACE VIEW v_dept_gtt AS
SELECT *
FROM TABLE(dept_gtt_pkg.f_getDept_tt)
/
Solution (2)
77. 77 of 90
CREATE OR REPLACE TRIGGER V_DEPT_GTT_IIUD
INSTEAD OF INSERT OR DELETE OR UPDATE ON V_DEPT_GTT
BEGIN
IF INSERTING THEN
IF :new.deptno IS NULL THEN
raise_application_error(-20001,'Deptno is mandatory');
END IF;
IF dept_gtt_pkg.v_pk_tt.exists(:new.deptno) THEN
raise_application_error(-20001,'Dept already exists');
END IF;
dept_gtt_pkg.v_dept_tt.extend;
dept_gtt_pkg.v_pk_tt(:new.deptno)
:=dept_gtt_pkg.v_dept_tt.last;
dept_gtt_pkg.v_dept_tt(dept_gtt_pkg.v_dept_tt.last):=
dept_gtt_ot(:new.deptno,:new.dname,:new.loc);
ELSIF DELETING THEN
IF :old.deptno IS NOT NULL AND
dept_gtt_pkg.v_pk_tt.exists(:old.deptno)
THEN
dept_gtt_pkg.v_dept_tt.delete
(dept_gtt_pkg.v_pk_tt(:old.deptno));
dept_gtt_pkg.v_pk_tt.delete(:old.deptno);
END IF;
...
Solution (3)
78. 78 of 90
ELSIF UPDATING THEN
IF :new.deptno IS NOT NULL AND :old.deptno!=:new.deptno THEN
IF dept_gtt_pkg.v_pk_tt.exists(:new.deptno) THEN
raise_application_error
(-20001,'Cannot have duplicate departments');
ELSE
dept_gtt_pkg.v_pk_tt(:new.deptno):=
dept_gtt_pkg.v_pk_tt(:old.deptno);
dept_gtt_pkg.v_pk_tt.delete(:old.deptno);
END IF;
END IF;
dept_gtt_pkg.v_dept_tt(dept_gtt_pkg.v_pk_tt(:new.deptno)):=
dept_gtt_ot(:new.deptno,:new.dname,:new.loc);
END IF;
END;
/
Solution (4)
79. 79 of 90
SQL> INSERT INTO v_dept_gtt SELECT * FROM dept WHERE deptno in
(10,20);
2 rows created.
SQL> select * from v_dept_gtt;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
SQL> INSERT INTO v_dept_gtt(deptno,loc) VALUES (50,'NEW JERSEY');
1 row created.
SQL> UPDATE v_dept_gtt SET dname='DEV' WHERE deptno=50;
1 row updated.
SQL> DELETE FROM v_dept_gtt WHERE deptno=20;
1 row deleted.
SQL> SELECT * FROM v_dept_gtt;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
50 DEV NEW JERSEY
Proof of Functionality
80. 80 of 90
Solution Impact
System impact:
Significantly less log file switches needed
No sudden slow-downs and hiccups.
Higher memory utilization and CPU overhead
Average response time increased from 0.25 seconds
to 0.3 seconds.
User impact:
Much more predictable performance = happy users
82. 82 of 90
Dangers of Views
Views are definitions, not data
Calling view multiple times = doing the same job
multiple times.
There may be a moment when persisting query
results may be more efficient.
Implementation of persistency depends upon your
requirements
Materialized views (lots of options)
Tables + manual refresh scripts
83. 83 of 90
Real World Example
Existing solution:
Reporting module is based on very complex views
After corporate merge, data volume quadrupled
Reports started to slow down.
Revised Solution:
Core views became materialized with nightly full
refresh.
Users gladly accepted daily data lag.
Advantage of using views from the beginning:
Simple server-side change did the job!
85. 85 of 90
Data Modeling Problem
ERD data model
Can be perfectly implemented as tables+constraints
Very limited
Class model
Much better tool to describe the world
Cannot be directly mapped to table structure
86. 86 of 90
Solution
Class model:
Table - perfectly relational
Package - implements UML-related functionality
View – presents class exactly as specified in class
model
88. 88 of 90
Illustration (2)
Generated view:
CREATE OR REPLACE VIEW person
AS
select
EMPLOYEE_OID PERSON_OID
,'Employee' PERSON_CD
,to_char(NameLast_TX||' '||NameFirst_TX) PERSON_DSP
,NAMEFIRST_TX NAMEFIRST_TX
,NAMELAST_TX NAMELAST_TX
from EMPLOYEE
union all
select
CONTACT_OID PERSON_OID
,'Contact' PERSON_CD
,to_char(NameLast_TX||' '||NameFirst_TX) PERSON_DSP
,NAMEFIRST_TX NAMEFIRST_TX
,NAMELAST_TX NAMELAST_TX
from CONTACT
89. 89 of 90
Summary
Views are significantly more than just stored
queries
... because they are interfaces to the outside world
(and even Oracle agrees ).
Effective utilization of the database is
impossible without deep knowledge of PL/SQL
… since it is closer to your data than any other
language environment.
It is important to check for new (or forgotten)
features
… because there are LOTS of them!
90. 90 of 90
Contact Information
Michael Rosenblum – mrosenblum@dulcian.com
Dulcian, Inc. website - www.dulcian.com
Blog: wonderingmisha.blogspot.com
Available NOW:
Oracle PL/SQL Performance
Tuning Tips & Techniques