sql改寫

哎呀我的天吶發表於2015-04-03

                   建立表和儲存過程

點選( 此處 )摺疊或開啟

  1. CREATE TABLE customers AS

  2. SELECT * FROM sh . customers where country_id in ( 52778 , 52772 ) ;


  3. CREATE OR REPLACE FUNCTION f_count_obj ( p_country_id VARCHAR2 )

  4.   RETURN NUMBER AS

  5.   v_count NUMBER ;

  6. BEGIN

  7.   SELECT COUNT ( * )

  8.      INTO v_count

  9.     FROM customers e26856649_1

  10.    WHERE country_id = p_country_id ;

  11.   RETURN v_count ;

  12. END ;

  13. /


點選( 此處 )摺疊或開啟

  1. 11 : 01 : 18 SQL > SET timing ON

  2. SET autotrace traceonly

  3. SELECT country_id , cust_first_name , f_count_obj ( country_id ) AS cnt FROM customers ;


  4. 4049 rows selected .


  5. Elapsed : 00 : 00 : 02 . 80


  6. Execution Plan

  7. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  8. Plan hash value : 2008213504


  9. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  10. | Id | Operation          |        Name | Rows | Bytes | Cost ( % CPU ) |      Time |

  11. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  12. |   0 | SELECT STATEMENT   |             | 3936 | 98400 |    33     ( ) | 00 : 00 : 01 |

  13. |   1 |   TABLE ACCESS FULL | CUSTOMERS | 3936 | 98400 |    33     ( ) | 00 : 00 : 01 |

  14. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


  15. Note

  16. - - - - -

  17.     - dynamic sampling used for this statement ( level = 2 )



  18. Statistics

  19. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  20.        4078  recursive calls

  21.       0  db block gets

  22.      437813  consistent gets

  23.       0  physical reads

  24.       0  redo size

  25.       99781  bytes sent via SQL * Net to client

  26.        3478  bytes received via SQL * Net from client

  27.     271  SQL * Net roundtrips to/from client

  28.       0  sorts ( memory )

  29.       0  sorts ( disk )

  30.        4049  rows processed


點選( 此處 )摺疊或開啟

  1. SQL > SELECT fetches , executions , sql_text

  2. FROM v$sql

  3. WHERE sql_text LIKE '%26856649 _1 %'

  4. AND sql_text NOT LIKE '%v$sql%'

  5. AND sql_text NOT LIKE '%OPT_DYN_SAMP%' ;


  6.    FETCHES EXECUTIONS   SQL_TEXT

  7. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  8.       4049     4049     SELECT COUNT ( * ) FROM CUSTOMERS E26856649_1 WHERE COUNTRY_ID = : B1

我們看到被解析 執行了4049次
下面我們新增如下引數

點選( 此處 )摺疊或開啟

  1. CREATE OR REPLACE FUNCTION f_count_obj2 ( p_country_id VARCHAR2 )

  2.   RETURN NUMBER DETERMINISTIC AS

  3.   v_count NUMBER ;

  4. BEGIN

  5.   SELECT

  6.    COUNT ( * )

  7.      INTO v_count

  8.     FROM customers e26856649_2

  9.    WHERE country_id = p_country_id ;

  10.   RETURN v_count ;

  11. END ;

  12. /

這裡指定別名為_2是為了區分v$sql中的sql_text

點選( 此處 )摺疊或開啟

  1. SELECT country_id , cust_first_name , f_count_obj2 ( country_id ) AS cnt FROM customers;

點選( 此處 )摺疊或開啟

  1. 11 : 47 : 07 SQL > SELECT fetches , executions , sql_text

  2.   FROM v$sql

  3.  WHERE sql_text LIKE '%26856649_2%'

  4.     AND sql_text NOT LIKE '%v$sql%'

  5.     AND sql_text NOT LIKE '%OPT_DYN_SAMP%' ;


  6.    FETCHES EXECUTIONS  SQL_TEXT

  7. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  8.        540      540     SELECT COUNT ( * ) FROM CUSTOMERS E26856649_2 WHERE COUNTRY_ID = : B1

結果看到這個被執行解析 540次,時間從2點幾秒,變成1.幾秒了。。。 。。。

有的時候,說函式很慢讓你改,你又不會改,那麼在函式里加這個引數,哈哈。

點選( 此處 )摺疊或開啟

  1. SELECT o . country_id ,

  2.        o . cust_first_name ,

  3.         ( SELECT COUNT ( * ) FROM customers t WHERE t . country_id = o . country_id ) AS cnt

  4.   FROM customers o

改成標量子查詢,時間不到1s

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29990276/viewspace-1485366/,如需轉載,請註明出處,否則將追究法律責任。

相關文章