Oracle中建立函數時的Deterministic選項

來源:互聯網
上載者:User

原文串連:http://blog.sina.com.cn/s/blog_6ff05a2c0100n2qo.html

我們平時在SQL語句的WHERE條件中使用函數是很常見的事情,考慮一下下面兩個SQL在執行機制上有什麼區別:
1. SELECT * FROM T WHERE col1 = UPPER('hello');
2. SELECT * FROM T WHERE col1 = DBMS_RANDOM.VALUE(1,100);
UPPER('hello')經過處理後會變成'HELLO',它相當於一個常量,因此第1個SQL類似於:
SELECT * FROM T WHERE col1 = 'HELLO';
而第2個SQL由於DBMS_RANDOM.VALUE(1,100)是不確定的,因此不能進行處理。這就導致T表有多少行,DBMS_RANDOM.VALUE這個函數就要執行多少次。而第1個SQL其實只執行了很少次數的UPPER函數,與表T的行數無關。
如果我們想自己寫一個函數SQUARE,實現平方的功能,那麼在下面的SQL中,SQUARE函數會執行多少次呢?
SELECT * FROM T WHERE col = SQUARE(10);
我們可以通過實驗來測試它,實驗的大致方法是:
1.建立一個包,包裡面定義一個NUMBER類型的變數,初始值設為0。
2.在我們自己定義的函數中增加一個將全域變數+1的賦值操作,這樣每調用一次該函數,全域變數就會增加1。
3.最後輸出全域變數的值,就是該函數被調用過的次數。當然每次測試前要將全域變數清零。
說到這裡我要提一個oracle函數的屬性,就是deterministic。它表示一個函數在輸入不變的情況下輸出是否確定,像oracle的內建函數UPPER,TRUNC等都是deterministic函數,而像DBMS_RANDOM.VALUE就不是deterministic函數,因為同樣的輸入不一定會導致同樣的輸出。
如果我們在定義SQUARE函數時沒有加deterministic屬性,那麼經過我的測試,SELECT * FROM T WHERE col = SQUARE(10);
這個SQL會執行ROWNUMBER次SQUARE函數,也就是如果表T有100行,那就執行100次。
如果我們在定義SQUARE函數時加上了deterministic屬性,那麼經過我的測試,SELECT * FROM T WHERE col = SQUARE(10);
這個SQL只會執行2次SQUARE函數,而不管表T有多少行。
因此給出結論:當我們自己建立函數時,如果能夠確定該函數是確定的,那就一定要加上deterministic屬性,這樣在where條件中使用該函數會提高一大截效能!否則,你寫的函數將來被多少人使用就是害了多少人

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.