Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Oracle tips and tricks

3,931 views

Published on

Published in: Technology, News & Politics
  • Be the first to comment

Oracle tips and tricks

  1. 1. Oracle Tips & Tricks Feb 10, 2011 Shane Zhang
  2. 2. AGENDA <ul><li>CASE Statement </li></ul><ul><li>Joins </li></ul><ul><li>Timestamp Data Type </li></ul><ul><li>Rename Tables, Columns </li></ul><ul><li>Merge Statement </li></ul><ul><li>Subqueries/With </li></ul><ul><li>Groupset/Rollup/Cube </li></ul><ul><li>Skip Scanning of Indexes </li></ul><ul><li>Index Compression </li></ul><ul><li>Index Organized Tables (IOT’s) </li></ul><ul><li>Temp Tables </li></ul>
  3. 3. CASE Statement vs. Decode <ul><li>2 ways to implement IF-THEN-ELSE logic within a SQL statement </li></ul><ul><li>CASE complies to ANSI SQL and is new to Oracle release 9i </li></ul><ul><li>DECODE Example (Oracle specific): </li></ul><ul><ul><li>SELECT last_name, job_cd, salary, </li></ul></ul><ul><ul><li>DECODE(job_cd, ‘IT’,salary*1.10, </li></ul></ul><ul><ul><li>‘ SALES’, salary*1.15, </li></ul></ul><ul><ul><li>salary*1.05) </li></ul></ul><ul><ul><li>FROM employees ; </li></ul></ul><ul><li>CASE Example: </li></ul><ul><ul><li>SELECT last_name, job_cd, salary, </li></ul></ul><ul><ul><li>CASE job_cd WHEN ‘IT’ THEN salary*1.10 </li></ul></ul><ul><ul><li>WHEN ‘SALES’ THEN salary*1.15 </li></ul></ul><ul><ul><li>ELSE salary*1.05 </li></ul></ul><ul><ul><li>END </li></ul></ul><ul><ul><li>FROM employees; </li></ul></ul>
  4. 4. ANSI Standard Join Syntax <ul><li>Oracle 9i introduced ANSI compliant join syntax </li></ul><ul><ul><li>INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, </li></ul></ul><ul><ul><li>FULL OUTER JOIN </li></ul></ul><ul><li>Oracle 9i – Outer Join (all rows from table on the “left” are retained in the result set) </li></ul><ul><ul><li>SELECT p.part_id, s.supplier_name </li></ul></ul><ul><ul><li>FROM part p left outer supplier s </li></ul></ul><ul><ul><li>ON p.supplier_id = s.supplier_id </li></ul></ul>
  5. 5. Join Operators <ul><li>Cross Join: </li></ul><ul><ul><li>Produces cross product resulting in Cartesian join. MOST LIKELY A MISTAKE! </li></ul></ul><ul><ul><li>SELECT empid, deptno FROM emp CROSS JOIN dept; </li></ul></ul><ul><ul><li>Without the operator: SELECT empid, deptno FROM emp, dept; </li></ul></ul><ul><li>Natural Join: </li></ul><ul><ul><li>Join based on like columns </li></ul></ul><ul><ul><li>SELECT empid, deptno, dname FROM emp NATURAL JOIN dept; </li></ul></ul><ul><ul><li>Without the operator: SELECT a.empid, a,deptno, b.dname FROM emp a, dept b WHERE a.deptno = b.deptno; </li></ul></ul>
  6. 6. Join Operators Cont’d <ul><li>ON: </li></ul><ul><ul><li>Much like WHERE clause. Can be used to join columns that </li></ul></ul><ul><ul><li>are named differently. </li></ul></ul><ul><ul><li>SELECT empid, dname FROM emp a JOIN dept b ON (a.deptno = b.department_no AND a.empid < 20); </li></ul></ul><ul><ul><li>Without the operator: SELECT empid, dname FROM emp a, dept b WHERE a.deptno = b.department_no AND a.empid < 20; </li></ul></ul>
  7. 7. New in 9i - Full Outer Joins <ul><li>Full Outer Syntax in Oracle 9i: </li></ul><ul><ul><li>SELECT p.part_id p, s.supplier_name </li></ul></ul><ul><ul><li>FROM part p FULL OUTER JOIN supplier s </li></ul></ul><ul><ul><li>ON p.supplier_id = s.supplier_id </li></ul></ul><ul><li>Result SQL is smaller in size; more elegant and more efficient than UNION method </li></ul>
  8. 8. Self Joins <ul><li>Create routes using lane segment </li></ul><ul><ul><li>SELECT a.origapt, a.destapt, b.destapt </li></ul></ul><ul><ul><li>From lanes a, lanes b </li></ul></ul><ul><ul><li>Where a.destapt=b.origapt; </li></ul></ul>
  9. 9. Renaming – Columns, Constraints, Tables <ul><li>Syntax </li></ul><ul><ul><li>Renaming a column: </li></ul></ul><ul><ul><ul><li>ALTER TABLE test RENAME COLUMN a_flg TO my_flg; </li></ul></ul></ul><ul><ul><li>Renaming a constraint: ALTER TABLE test RENAME constraint a_flg_pk TO </li></ul></ul><ul><ul><li>a_flg_pk_new; </li></ul></ul><ul><ul><li>Renaming a table: </li></ul></ul><ul><ul><ul><li>ALTER TABLE test RENAME to test_new; </li></ul></ul></ul>
  10. 10. Top N Analysis <ul><li>SELECT [column_list], ROWNUM </li></ul><ul><li>FROM (SELECT [column_list] </li></ul><ul><li>FROM table </li></ul><ul><li>ORDER BY Top-N_column) </li></ul><ul><li>WHERE ROWNUM <= N; </li></ul><ul><li>Rank by group </li></ul><ul><li>SELECT Empno, Ename, Job, Mgr, Hiredate, Sal </li></ul><ul><li>FROM </li></ul><ul><li>(SELECT Empno, Ename, Job, Mgr, Hiredate, Sal, </li></ul><ul><li>RANK() OVER </li></ul><ul><li>(ORDER BY SAL Desc NULLS LAST) AS Emp_Rank </li></ul><ul><li>FROM Emp </li></ul><ul><li>ORDER BY SAL Desc NULLS LAST) </li></ul><ul><li>WHERE Emp_Rank < 6; </li></ul>
  11. 11. Windowing Function <ul><li>Three month moving average </li></ul><ul><li>SELECT month, SUM(tot_sales) monthly_sales, </li></ul><ul><li>AVG(SUM(tot_sales)) OVER (ORDER BY month </li></ul><ul><li>ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) rolling_avg </li></ul><ul><li>FROM orders </li></ul><ul><li>WHERE year = 2001 </li></ul><ul><li>AND region_id = 6 </li></ul><ul><li>GROUP BY month </li></ul><ul><li>ORDER BY month; </li></ul><ul><li>Cumulative total </li></ul><ul><li>SELECT month, </li></ul><ul><li>SUM(tot_sales) monthly_sales, </li></ul><ul><li>SUM(SUM(tot_sales)) OVER (ORDER BY month </li></ul><ul><li>ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) running_total </li></ul><ul><li>FROM orders </li></ul><ul><li>WHERE year = 2001 </li></ul><ul><li>AND region_id = 6 </li></ul><ul><li>GROUP BY month </li></ul><ul><li>ORDER BY month; </li></ul>
  12. 12. Traverse the Hierarchical tree <ul><li>Organization Chart </li></ul><ul><li>SELECT level, lname, emp_id, manager_emp_id </li></ul><ul><li>FROM employee </li></ul><ul><li>START WITH manager_emp_id IS NULL </li></ul><ul><li>CONNECT BY manager_emp_id = PRIOR emp_id; </li></ul>Does JONES have any authority over BLAKE?“ SELECT * FROM employee WHERE lname = 'BLAKE' START WITH lname = 'JONES' CONNECT BY manager_emp_id = PRIOR emp_id;
  13. 13. XML <ul><li>Create XML elements from table </li></ul><ul><li>SELECT XMLElement(&quot;supplier_id&quot;, s.supplier_id) || </li></ul><ul><li>XMLElement(&quot;name&quot;, s.name) xml_fragment </li></ul><ul><li>FROM supplier s; </li></ul>
  14. 14. Using subquery <ul><li>Inline View – subquery in the from clause Inline views are always executed prior to the containing query and, thus, may not reference columns from other tables or inline views from the same query. </li></ul><ul><li>SELECT [column_list], ROWNUM FROM (SELECT [column_list] </li></ul><ul><li>FROM table ORDER BY Top-N_column) WHERE ROWNUM <= N; </li></ul><ul><li>Nested query – subquery in the where clause </li></ul><ul><li>SELECT lname FROM employee WHERE salary > (SELECT AVG(salary) </li></ul><ul><li>FROM employee); </li></ul><ul><li>select ename ,sal ,deptno from emp a where </li></ul><ul><li>a.sal < (select avg(sal) from emp b </li></ul><ul><li> where a.deptno = b.deptno) </li></ul><ul><li>order by deptno; </li></ul>
  15. 15. Using subquery – Cont’d <ul><li>You can update through a view </li></ul><ul><li>update ( select a.data old_data, b.data new_data </li></ul><ul><li>from table1 A, table2 B </li></ul><ul><li>where a.key = b.key ) </li></ul><ul><li>set old_Data = new_data </li></ul><ul><li>Delete duplicate records </li></ul><ul><li>DELETE FROM our_table WHERE rowid not in </li></ul><ul><li>(SELECT MIN(rowid) FROM our_table </li></ul><ul><li>GROUP BY column1, column2, column3... ;; </li></ul>
  16. 16. With Clause <ul><li>To eliminate the inefficiency of executing the same subquery multiple times, Oracle introduced the WITH clause in the Oracle9i release. Using the WITH clause, you can place the subquery that calculates the average salary at the top of the query and reference it throughout the query: The WITH clause creates a temporary data set called, in this case, avg_sal, </li></ul><ul><li>WITH avg_sal AS (SELECT AVG(salary) val FROM employee) </li></ul><ul><li>SELECT e.emp_id, e.lname, e.fname, </li></ul><ul><li>(SELECT ROUND(e.salary - val) FROM avg_sal) above_avg </li></ul><ul><li>FROM employee e </li></ul><ul><li>WHERE e.salary > (SELECT val FROM avg_sal); </li></ul>
  17. 17. Having Clause <ul><li>SELECT department, SUM(sales) as &quot;Total sales&quot; </li></ul><ul><li>FROM order_details GROUP BY department </li></ul><ul><li>HAVING SUM(sales) > 1000; </li></ul><ul><li>SELECT department, COUNT(*) as &quot;Number of employees&quot; </li></ul><ul><li>FROM employees </li></ul><ul><li>WHERE salary > 25000 </li></ul><ul><li>GROUP BY department </li></ul><ul><li>HAVING COUNT(*) > 10; </li></ul>
  18. 18. Oracle 9i – TIMESTAMP Data Type <ul><li>Extension of the DATE data type </li></ul><ul><li>Stores year, month, & day of the date + hour, minute, second and fractional seconds </li></ul><ul><ul><li>select current_timestamp from dual </li></ul></ul><ul><ul><li>13:53:29 SQL> / </li></ul></ul><ul><ul><li>CURRENT_TIMESTAMP </li></ul></ul><ul><ul><li>--------------------------------------------------------------------------- </li></ul></ul><ul><ul><li>14-MAR-05 01.53.30.458397 PM -06:00 </li></ul></ul><ul><ul><li>insert into time_stamp_example (select current_timestamp from dual); </li></ul></ul><ul><ul><li>1 row created. </li></ul></ul><ul><ul><li>13:46:13 SQL> insert into time_stamp_example (select sysdate from dual) ; </li></ul></ul><ul><ul><li>1 row created. </li></ul></ul><ul><ul><li>Elapsed: 00:00:00.02 </li></ul></ul><ul><ul><li>13:46:23 SQL> select * from time_stamp_example; </li></ul></ul><ul><ul><li>EXAMPLE_DATE </li></ul></ul><ul><ul><li>--------------------------------------------------------------------------- </li></ul></ul><ul><ul><li>14-MAR-05 01.46.23.0000 PM </li></ul></ul><ul><ul><li>1 row selected. </li></ul></ul><ul><ul><li>Elapsed: 00:00:00.00 </li></ul></ul>
  19. 19. Information of a table <ul><li>Find out the creation date of a table </li></ul><ul><li>select substr(object_name,1,15),created from obj; </li></ul><ul><li>Find out who has what privileges on your tables </li></ul><ul><li>select table_name,grantee,privilege from user_tab_privs; </li></ul>
  20. 20. Information on Space <ul><li>Get an estimation of the size of a table, get avg_row_len and pctfree information from user_tables </li></ul><ul><li>tablesize=number of rows*avg_row_len*(1+pctfree/100) </li></ul><ul><li>SQL> select num_rows,pct_free,avg_row_len from user_tables where table_name='DOCDATA_IND'; </li></ul><ul><li>Find out the total free space available to current use </li></ul><ul><li>select tablespace_name,sum(bytes/1000) from user_free_space group by tablespace_name </li></ul><ul><li>Find out how much space used and what is your quota </li></ul><ul><li>select * from user_ts_quota; </li></ul>
  21. 21. Group By Enhancements – Grouping Set select count(*) CNT, deptno, 'summary' as job from emp group by deptno UNION ALL select count(*), deptno, job from emp group by deptno, job / CNT DEPTNO JOB --- ---------- --------- 3 10 Summary 1 10 PRESIDENT 1 10 MANAGER 1 10 CLERK 5 20 Summary 1 20 MANAGER 2 20 CLERK 2 20 ANALYST 6 30 Summary 4 30 SALESMAN 1 30 MANAGER 1 30 CLERK select count(*) CNT, deptno , CASE GROUPING_ID(job) WHEN 1 THEN 'Summary' ELSE job END AS job from emp group by GROUPING SETS ( (deptno) , (deptno, job ) ) / CNT DEPTNO JOB --- ---------- --------- 3 10 Summary 1 10 PRESIDENT 1 10 MANAGER 1 10 CLERK 5 20 Summary 1 20 MANAGER 2 20 CLERK 2 20 ANALYST 6 30 Summary 4 30 SALESMAN 1 30 MANAGER 1 30 CLERK Union all method, multiple table scan , slow New method, fast
  22. 22. Group By Enhancements – ROLLUP / CUBE <ul><li>ROLLUP - Used for subtotaling along a hierarchical dimension such as time or geography. </li></ul><ul><li>CUBE = ROLLUP + other combinations </li></ul><ul><li>Can simplify and speed up population and maintenance of summary tables. </li></ul>
  23. 23. ROLLUP Example Query <ul><li>SELECT a.shp_rcv_src_cd, </li></ul><ul><li>a.tndr_type_cd, </li></ul><ul><li>SUM(a.nbr_of_pkgs), </li></ul><ul><li>SUM(a.net_rev), </li></ul><ul><li>SUM(a.ratd_wgt) </li></ul><ul><li>FROM shipment a, </li></ul><ul><li>location b </li></ul><ul><li>WHERE a.shp_dt_yyyymm='200312' </li></ul><ul><li>and a.shp_rcv_src_cd in ('3','4','5') </li></ul><ul><li>and b.loc_nbr=a.loc_nbr </li></ul><ul><li>and b.hist_yyyymm=a.shp_dt_yyyymm </li></ul><ul><li>and b.drpbx_type_cd in ('IC','IS','IW','IM','OM','IY','OW') </li></ul><ul><li>GROUP BY rollup(shp_rcv_src_cd,tndr_type_cd) </li></ul><ul><li>ORDER BY shp_rcv_src_cd,tndr_type_cd </li></ul>
  24. 24. ROLLUP Example Output SHP_RCV_SRC_CD TNDR_TYPE_CD SUM(A.NBR_OF_PKGS) SUM(A.NET_REV) SUM(A.RATD_WGT) 3 CCC 15204 452297 76297 3 DRPF 688169 12653173 3509281 3 SOLD 570572 8422926 3112950 3 ? 1273945 21528396 6698529 4 CCC 26 1414 100 4 DRPF 484 28301 4350 4 SOLD 759 23706 5306 4 ? 1269 53421 9756 5 CCC 18 975 80 5 DRPF 2123 101847 12510 5 SOLD 230 7026 1625 5 ? 2371 109849 14215 ? ? 1277585 21691666 6722500
  25. 25. CUBE Example Query <ul><li>SELECT a.shp_rcv_src_cd, </li></ul><ul><li>a.tndr_type_cd, </li></ul><ul><li>SUM(a.nbr_of_pkgs), </li></ul><ul><li>SUM(a.net_rev), </li></ul><ul><li>SUM(a.ratd_wgt) </li></ul><ul><li>FROM shipment a, </li></ul><ul><li>location b </li></ul><ul><li>WHERE a.shp_dt_yyyymm='200312' </li></ul><ul><li>and a.shp_rcv_src_cd in ('3','4','5') </li></ul><ul><li>and b.loc_nbr=a.loc_nbr </li></ul><ul><li>and b.hist_yyyymm=a.shp_dt_yyyymm </li></ul><ul><li>and b.drpbx_type_cd in ('IC','IS','IW','IM','OM','IY','OW') </li></ul><ul><li>GROUP BY cube(shp_rcv_src_cd,tndr_type_cd) </li></ul><ul><li>ORDER BY shp_rcv_src_cd,tndr_type_cd </li></ul>
  26. 26. CUBE Example Output SHP_RCV_SRC_CD TNDR_TYPE_CD SUM(A.NBR_OF_PKGS) SUM(A.NET_REV) SUM(A.RATD_WGT) 3 CCC 15204 452297 76297 3 DRPF 688169 12653173 3509281 3 SOLD 570572 8422926 3112950 3 ? 1273945 21528396 6698529 4 CCC 26 1414 100 4 DRPF 484 28301 4350 4 SOLD 759 23706 5306 4 ? 1269 53421 9756 5 CCC 18 975 80 5 DRPF 2123 101847 12510 5 SOLD 230 7026 1625 5 ? 2371 109849 14215 ? CCC 15248 454686 76478 ? DRPF 690776 12783322 3526141 ? SOLD 571561 8453658 3119881 ? ? 1277585 21691666 6722500
  27. 27. MERGE <ul><li>Performs single step INSERT and UPDATE </li></ul><ul><li>INTO clause specifies the target table </li></ul><ul><li>USING clause specifies the source </li></ul><ul><li>Key exists: Update performed </li></ul><ul><li>Key does not exist: Row inserted </li></ul>
  28. 28. MERGE Cont’d <ul><li>SQL> select * from my_table; </li></ul><ul><li>ACCT_NBR CO_NM </li></ul><ul><li>---------------- ------------------------------ </li></ul><ul><li>1 GE </li></ul><ul><li>1 row selected. </li></ul><ul><li>SQL>select * from my_staging_table; </li></ul><ul><li>ACCT_NBR CO_NM </li></ul><ul><li>---------------- ------------------------------ </li></ul><ul><li>1 GE </li></ul><ul><li>2 Oracle Corp </li></ul><ul><li>2 rows selected. </li></ul>
  29. 29. MERGE Cont’d <ul><li>SQL> merge into my_table a </li></ul><ul><li>using my_staging_table b on (a.acct_nbr = b.acct_nbr) </li></ul><ul><li>when matched then </li></ul><ul><li>update set a.co_nm = b.co_nm </li></ul><ul><li>when not matched then </li></ul><ul><li>insert (a.acct_nbr, a.co_nm) </li></ul><ul><li>values (b.acct_nbr, b.co_nm); </li></ul><ul><li>2 rows merged. </li></ul>
  30. 30. MERGE Cont’d <ul><li>SQL>select * from my_table; </li></ul><ul><li>ACCT_NBR CO_NM </li></ul><ul><li>---------------- ------------------------------ </li></ul><ul><li>1 GE </li></ul><ul><li>2 Oracle Corp </li></ul><ul><li>2 rows selected. </li></ul>
  31. 31. Skip Scanning of Indexes <ul><li>Earlier versions: Index will NOT be used if the WHERE clause columns are not in the leading edge of the query. </li></ul><ul><li>With Oracle9i: </li></ul><ul><ul><li>This is not an issue because of skip scanning of indexes feature. </li></ul></ul><ul><ul><li>Indexes may be used regardless of the order the columns are specified on WHERE stmt. </li></ul></ul><ul><ul><li>Bitmap indexes cannot take advantage of this feature. </li></ul></ul>
  32. 32. Index Compression <ul><li>Compression option on indexes was introduced in Oracle 8i; but enhanced features are easier to use in Oracle 9i </li></ul><ul><li>A properly compressed index would use a smaller number of “leaf” blocks to store the index…resulting in lower i/o when the index is used = better performance on index scans. </li></ul><ul><li>At creation time, compress the 1 st 2 columns of a composite index: </li></ul><ul><ul><li>CREATE INDEX my_idx ON my_tbl(col1, col2, col3) compress 2; </li></ul></ul><ul><li>Index already exists, compress first 2 columns: </li></ul><ul><ul><li>ALTER index my_idx rebuild compress 2; </li></ul></ul>
  33. 33. All my Indexes should be compressed, right? <ul><li>No - should not ALWAYS compress indexes. </li></ul><ul><li>How do I know if I should compress and what columns to compress? </li></ul><ul><li>Use VALIDATE INDEX: </li></ul><ul><ul><li>VALIDATE INDEX my_idx; </li></ul></ul><ul><li>Look at OPT_CMPR_COUNT and OPT_COMPR_PCTSAVE columns: </li></ul><ul><ul><li>SELECT opt_cmpr_countm, opt_cmpr_pctsave FROM index_stats; </li></ul></ul>
  34. 34. Temporary Tables <ul><li>Not really a 9i feature. Enhanced/bug fixed </li></ul><ul><li>Holds session based or transaction based data. </li></ul><ul><li>Inserts by user A not visible to user B </li></ul><ul><li>Data automatically purged at the end of the session/transaction but the table structure will be retained. </li></ul><ul><li>CREATE TABLE: key word GLOBAL TEMPORARY TABLE </li></ul>
  35. 35. Temporary Table Cont’d <ul><li>Example: </li></ul><ul><li>SQL>CREATE GLOBAL TEMPORARY TABLE t_transaction </li></ul><ul><li>(c VARCHAR2(4000)) ON COMMIT DELETE ROWS; </li></ul><ul><li>Table created. </li></ul><ul><li>SQL> CREATE GLOBAL TEMPORARY TABLE t_session </li></ul><ul><li>(c VARCHAR2(4000)) ON COMMIT PRESERVE ROWS; </li></ul><ul><li>Table created. </li></ul>
  36. 36. Temporary Table Cont’d <ul><li>SQL> INSERT INTO t_transaction (c) </li></ul><ul><li>VALUES ('data persists for the transaction'); </li></ul><ul><li>1 row created. </li></ul><ul><li>SQL> INSERT INTO t_session (c) </li></ul><ul><li>VALUES ('data persists for the session'); </li></ul><ul><li>1 row created. </li></ul><ul><li>SQL> commit; </li></ul>
  37. 37. Temporary Table Cont’d <ul><li>Commit complete. </li></ul><ul><li>SQL> SELECT * FROM t_transaction; </li></ul><ul><li>no rows selected =========> the transaction is over, the data is gone </li></ul><ul><li>SQL> SELECT * FROM t_session; </li></ul><ul><li>C </li></ul><ul><li>---------------------------------------- </li></ul><ul><li>data persists for the session </li></ul><ul><li>1 row selected. </li></ul>

×