[转]谈谈where条件中函数的使⽤(deterministic)
我们平时在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的⾏数⽆关。
oracle中trunc函数用法如果我们想⾃⼰写⼀个函数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条件中使⽤该函数会提⾼⼀⼤截性能!否则,你写的函数将来被多少⼈使⽤就是害了多少⼈!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论