17
Technical Skills Enhancement – PL/SQL Best practices

Oracle SQL, PL/SQL best practices

Embed Size (px)

Citation preview

Page 1: Oracle SQL, PL/SQL best practices

Technical Skills Enhancement – PL/SQL Best practices

Page 2: Oracle SQL, PL/SQL best practices

Objectives

At the end of this training, you will be able to:

• Understand best practices in SQL and PL/SQL

Page 3: Oracle SQL, PL/SQL best practices

Agenda

– Indexes

– Logical tuning

– Benefits of using exists

– Avoid distinct

– Know your data, know your query

– Check code behind views

Page 4: Oracle SQL, PL/SQL best practices

PL/SQL Tuning for performance- Indexes

• Indexes help Oracle find rows easily as rowid references are stored in Indexes.

• Similar to reading from a book

Guidelines for creating indexes

• Do create indexes on– Columns frequently used in WHERE clause

– Columns used in joins

• Avoid creating indexes on– Columns whose data is updated frequently

Indexes – not too many, not too few

Create indexes only when it is absolutely necessary. While indexes aid in improving the performance of queries, too many indexes on a table could drastically slow down the inserts and updates to the table.

Page 5: Oracle SQL, PL/SQL best practices

PL/SQL Tuning for performance- Indexes

Note: Although it is not a standard practice to create indexes on platform tables (starting with SI_), sometimes when performance issues are seen it might require an index to be created. In this case, ensure that care is taken to recreate the indexes after each platform upgrade.

Guidelines for indexes• When creating composite indexes, the order of columns is important. The

column that is more frequently queried must be put first. If the columns have a parent-child relation, then the parent column should come first.

Script : IndexBestPractices.sql

– Missing leading index column in join Can’t use index• Eg: Composite index on STATE, CITY

where state = 'TX' [Index used]

where city = 'DALLAS' [Index Not Used]

where state = 'TX' and city = 'DALLAS' [Index Used]

Page 6: Oracle SQL, PL/SQL best practices

PL/SQL Tuning for performance- Indexes

– NOT, != and <> disable index use

where state not in ('TX', 'FL','OH')[Index Not used]

where state != 'TX' [Index Not used]

  Instead try to use IN or = whenever possible

– NULL value references can never use indexes

where state IS NULL [Index Not used]

where state IS NOT NULL [Index Not used]

– Expression references can never use indexes

  where substr(city,1,3) = 'DAL' [Index Not used]

where city like 'DAL%' [Index Used]

where city || state = 'DALLASTX' [Index Not used]

where salary * 12 >= 24000 [Index Not used]

where salary >= 2000 [Index Used]

Page 7: Oracle SQL, PL/SQL best practices

PL/SQL Tuning for performance- Indexes

• Avoid using functions on table columns in WHERE clause, instead use local variables. 

• Functions on indexed columns prevent Index scans, unless there is a function based index on the column.

• DO NOT: “where trunc(created_date) > …”

• BETTER: “where created_date > “

• DO NOT: select * from accounts where account_status = get_system_constants(‘SUSPENDED STATUS’);

• BETTER: l_suspended_status := get_system_constants(‘SUSPENDED STATUS’);

select * from accounts where account_status = l_suspended_status;

Page 8: Oracle SQL, PL/SQL best practices

PL/SQL Tuning for performance – The benefits of using EXISTS

Lesson Learned

In a query joining multiple tables if some tables are not represented in the SELECT clause (ie : columns from those tables are not in SELECT clause) those tables can be moved from JOIN to EXISTS.

EXISTS is always better than using JOIN(in some cases) or IN. This is because once Oracle finds the first record that fulfills the subquery in the EXISTS clause, it does not bother to check the remaining records.

Consider the below query- SELECT user_nameFROM usersWHERE user_id IN (SELECT user_id FROM user_org_roles)

FOR EACH user_id IN USERS FOR EACH user_id IN USER_ORG_ROLES IF USERS.user_id = USER_ORG_ROLES.user_id THEN TRUE; END IF; END LOOP;END LOOP;

100 users x 1000 org roles = 100,000 comparisons!

Page 9: Oracle SQL, PL/SQL best practices

PL/SQL Tuning for performance – The benefits of using EXISTS

Rewriting using EXISTSSELECT a.user_nameFROM users aWHERE EXISTS (SELECT b.user_id FROM user_org_roles b WHERE b.user_id = a.user_id)

FOR EACH user_id IN USERS

IF user_id EXISTS in USER_ORG_ROLES THEN

RETURN row;

END IF;

END LOOP;

100 users = 100 comparisons!

Page 10: Oracle SQL, PL/SQL best practices

PL/SQL Tuning for performance – Avoid DISTINCT

Reqmt : Users in organization 100000

SELECT u.user_id , u.user_nameFROM users u , user_org_roles rWHERE u.user_id = r.user_idAND r.org_id = 100000;USER_ID USER_NAME------------ -------------------------------100001 JOHN DOE100001 JOHN DOE

Lazy developer approach

SELECT DISTINCT u.user_id , u.user_nameFROM users u , user_org_roles rWHERE u.user_id = r.user_idAND r.org_id = 100000;

USER_ID USER_NAME------------ -------------------------------100001 JOHN DOE

Page 11: Oracle SQL, PL/SQL best practices

PL/SQL Tuning for performance –Avoid DISTINCT

• DISTINCT

– Fetch All Rows satisfying the join

– Sort and Filter duplicate values

– Uses TEMP tablespace if resultset is large

• Better way to fetch unique values using EXISTS

SELECT u.user_id , u.user_nameFROM users uWHERE EXISTS ( SELECT 1 FROM user_org_roles r WHERE u.user_id = r.user_id AND r.org_id = 100000 )

Page 12: Oracle SQL, PL/SQL best practices

SQL Tuning – HAVING vs WHERE• Use HAVING only to filter on aggregate functions (count, sum, avg etc)

• Use WHERE to filter on table columns

Script : SQLBestPractices.sql

Least Efficient:

The statement below is a syntactically correct statement. It will produce the expected result. However filter is done after all the sorting and counting is complete.

SELECT job, city, state, COUNT(empno) FROM city_data

GROUP BY job, city, state

HAVING job='CLERK';

Correct Usage

SELECT job, city, state, COUNT(empno) FROM city_data

WHERE job='CLERK'

GROUP BY job, city, state;

Page 13: Oracle SQL, PL/SQL best practices

SQL Tuning – UNION vs UNION ALL• The UNION operation sorts the result set to eliminate duplicate rows

• UNION ALL includes duplicate rows and does not require a sort.

• Unless you require that the duplicate rows be eliminated, or you are certain that the member queries do not produce duplicate data, use UNION ALL

SELECT empno, ename, deptno FROM emp_10

UNION

SELECT empno, ename, deptno FROM emp_20;

--Better performance

SELECT empno, ename, deptno FROM emp_10

UNION ALL

SELECT empno, ename, deptno FROM emp_20;

Page 14: Oracle SQL, PL/SQL best practices

PL/SQL coding guidelines - General

– Use equality first.

– Use range operators only where equality does not apply.

– Avoid use of negatives in the form of “ != ” or ” NOT”.

– Avoid LIKE pattern matching.

– Try to retrieve specific rows and in small numbers.

– Filter from large tables first to reduce rows joined. Retrieve tables in order from the most highly filtered table downwards; preferably the largest table has the most filtering applied.

– The most highly filtered table is the table having the smallest percentage of its rows retrieved, preferably the largest table.

– Use indexes wherever possible except for very small tables.

– Let the Optimizer do its job.

Page 15: Oracle SQL, PL/SQL best practices

PL/SQL coding guidelines - General

• Modularize with top-down design; keep executable sections small and easy to read

• Modularize to reduce complexity, make your tasks manageable, and make your resulting code maintainable

• Avoid multiple RETURN statements in executable section, instead save values in variables & return the variable

• Avoid lengthy sections of code, and spaghetti code• Code sections should be self documenting• Avoid any code redundancies

Page 16: Oracle SQL, PL/SQL best practices

PL/SQL Tuning for performance

• There will always be many ways to write a query or PL/SQL program to fulfill a requirement.

• By applying the above concepts and using iterative methods you can figure out which method yields THE BEST performance.

Page 17: Oracle SQL, PL/SQL best practices

Thank YouFeedback, Questions, Discussion