避免SQL中的函式呼叫

LuiseDalian發表於2014-01-17

SQL編碼中,儘量避免在SQL中進行函式呼叫,否則會產生大量的遞迴呼叫而影響效能。

如果用表連線來代替函式呼叫,往往會更高效。

點選(此處)摺疊或開啟

  1. DROP TABLE people;
  2. DROP TABLE sex;
  3. CREATE TABLE people (first_name VARCHAR2(200), last_name VARCHAR2(200), sex_id NUMBER);
  4. CREATE TABLE sex(NAME VARCHAR2(20), sex_id NUMBER);
  5. INSERT INTO people(first_name, last_name, sex_id) SELECT object_name, object_type, 1 FROM dba_objects;

  6. INSERT INTO sex(name, sex_id) VALUES(\'男\' ,1);
  7. INSERT INTO sex(name, sex_id) VALUES(\'女\' ,2);
  8. INSERT INTO sex(name, sex_id) VALUES(\'不詳\' ,3);
  9. COMMIT;

  10. CREATE OR REPLACE FUNCTION get_sex_name(p_id sex.sex_id%TYPE) RETURN sex.name%TYPE
  11. IS
  12.   v_name sex.name%TYPE;
  13. BEGIN
  14.   SELECT NAME INTO v_name FROM sex WHERE sex_id = p_id;
  15.   RETURN v_name;
  16. END;
  17. /

  18. --查詢people表的資訊,同時通過sex表,獲取人員的性別資訊
  19. SET autotrace traceonly
  20. SET timing ON
  21. SELECT sex_id, first_name || \' \' || last_name AS full_name, get_sex_name(sex_id) AS gender FROM people;

  22. 75559 rows selected.
  23. Elapsed: 00:00:04.68

  24. Execution Plan
  25. ----------------------------------------------------------
  26. Plan hash value: 2528372185


點選(此處)摺疊或開啟

  1. SELECT p.sex_id, p.first_name || \' \' || p.last_name AS full_name, sex.name
  2. from people p, sex where sex.sex_id = p.sex_id;

  3. 75559 rows selected.

  4. Elapsed: 00:00:00.49

  5. Execution Plan
  6. ----------------------------------------------------------
  7. Plan hash value: 1973058250

 

函式呼叫

表連線

執行時間

4.68

0.49

遞迴呼叫

75592

9

邏輯讀

534500

5564


點選(此處)摺疊或開啟

  1. --驗證函式呼叫的次數,就是執行計劃中遞迴呼叫的次數
  2. --在函式中增加 dbms_application_info.set_client_info(userenv(\'client_info\')+1)。
  3. CREATE OR REPLACE FUNCTION get_sex_name(p_id sex.sex_id%TYPE) RETURN sex.name%TYPE IS
  4.   v_name sex.name%TYPE;
  5. BEGIN
  6.   SELECT NAME INTO v_name FROM sex WHERE sex_id = p_id;
  7.   dbms_application_info.set_client_info(userenv(\'client_info\') + 1);
  8.   RETURN v_name;
  9. END;

  10. exec dbms_application_info.set_client_info(\'0\');
  11. SET autotrace traceonly
  12. SELECT sex_id, first_name || \' \' || last_name AS full_name, get_sex_name(sex_id) AS gender FROM people;

  13. 75559 rows selected.

  14. Elapsed: 00:00:05.62

  15. Execution Plan
  16. ----------------------------------------------------------
  17. Plan hash value: 2528372185



點選(此處)摺疊或開啟

  1. --檢視函式呼叫次數
  2. SELECT userenv(\'client_info\') FROM dual;
  3. USERENV(\'CLIENT_INFO\')
  4. ----------------------------------------------------------------
  5. 75559


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

相關文章