Lets say we have a table which has 6million records.
CREATE TABLE MYTABLE
(
KEY1 NUMBER(15),
ANALYSENO NUMBER(15),
ADDRESSNO NUMBER(15),
ABC NUMBER(3),
ABCDETAIL CLOB
)
AND i have two queries.
first one:
Select m.*,
CASE WHEN dbms_lob.INSTR(m.ABCDETAIL,'ABC$$') = 0 THEN '' ELSE
dbms_lob.SUBSTR(m.ABCDETAIL,dbms_lob.INSTR(m.ABCDETAIL,'##AAA')-dbms_lob.INSTR(m.ABCDETAIL,'ABC$$')-10,dbms_lob.INSTR(m.ABCDETAIL,'ABC')+10) END) as SOMECALC
from MYTABLE m
where m.ABC = 1
and ROWNUM < 1000
and CASE WHEN dbms_lob.INSTR(m.ABCDETAIL,'ABC$$') = 0 THEN '' ELSE
dbms_lob.SUBSTR(m.ABCDETAIL,dbms_lob.INSTR(m.ABCDETAIL,'##AAA')-dbms_lob.INSTR(m.ABCDETAIL,'ABC$$')-10,dbms_lob.INSTR(m.ABCDETAIL,'ABC')+10) END like '%AAA%';
second one:
Select a.* from
(Select m.*,
CASE WHEN dbms_lob.INSTR(m.ABCDETAIL,'ABC$$') = 0 THEN '' ELSE
dbms_lob.SUBSTR(m.ABCDETAIL,dbms_lob.INSTR(m.ABCDETAIL,'##AAA')-dbms_lob.INSTR(m.ABCDETAIL,'ABC$$')-10,dbms_lob.INSTR(m.ABCDETAIL,'ABC')+10) END as SOMECALC
from MYTABLE m
where m.ABC = 1
and ROWNUM < 1000) a
where a.SOMECALC like '%AAA%';
The only difference is that in second query calculation functions are not used on where statement. And be careful i m using ROWNUM < 1000 statement for where query.
So the questions are the following
1- is there any difference between two queries?
2- can we say that ROWNUM < 1000 statement calculated lastly in all statement execution?
3- using some functions (length, case when, instr etc) lazy evaluted?
答案 0 :(得分:1)
是的,两个查询之间存在差异。
在第一个查询中,您要说的是获取与所有其他过滤条件匹配的前999行。
在第二个查询中,您说要获取m.abc = 1的前999行,然后过滤那些somecalc字段为'%AAA%'的行。
最终,第二个查询显示的行数可能会减少。如果您将log4js
谓词移动到第二个查询的外部查询,那么您将拥有与第一个查询相同的查询。
答案 1 :(得分:0)
首先,两个查询都有语法错误。 CASE表达式中有一个额外的右括号。
无论如何,回到你原来的问题:
1-两个查询之间有什么区别吗?
是
我们可以说ROWNUM&lt;最后在所有语句执行中计算的1000语句?
没有
区别在于过滤谓词。要理解它,请比较解释计划:
查询1
SQL> set autot on explain
SQL> SELECT m.*,
2 CASE
3 WHEN dbms_lob.INSTR(m.ABCDETAIL,'ABC$$') = 0
4 THEN ''
5 ELSE dbms_lob.SUBSTR(m.ABCDETAIL,dbms_lob.INSTR(m.ABCDETAIL,'##AAA')-
6 dbms_lob.INSTR(m.ABCDETAIL,'ABC$$')-10,dbms_lob.INSTR(m.ABCDETAIL,'ABC')+10)
7 END AS SOMECALC
8 FROM MYTABLE m
9 WHERE m.ABC = 1
10 AND ROWNUM < 1000
11 AND
12 CASE
13 WHEN dbms_lob.INSTR(m.ABCDETAIL,'ABC$$') = 0
14 THEN ''
15 ELSE dbms_lob.SUBSTR(m.ABCDETAIL,dbms_lob.INSTR(m.ABCDETAIL,'##AAA')-
16 dbms_lob.INSTR(m.ABCDETAIL,'ABC$$')-10,dbms_lob.INSTR(m.ABCDETAIL,'ABC')+10)
17 END LIKE '%AAA%';
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 1231656364
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2054 | 2 (0)| 00:00:01 |
|* 1 | COUNT STOPKEY | | | | | |
|* 2 | TABLE ACCESS FULL| MYTABLE | 1 | 2054 | 2 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<1000)
2 - filter("M"."ABC"=1 AND CASE "DBMS_LOB"."INSTR"("M"."ABCDETAIL",'A
BC$$') WHEN 0 THEN '' ELSE "DBMS_LOB"."SUBSTR"("M"."ABCDETAIL","DBMS_LOB
"."INSTR"("M"."ABCDETAIL",'##AAA')-"DBMS_LOB"."INSTR"("M"."ABCDETAIL",'A
BC$$')-10,"DBMS_LOB"."INSTR"("M"."ABCDETAIL",'ABC')+10) END LIKE
'%AAA%')
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
查询2
SQL> SELECT a.*
2 FROM
3 (SELECT m.*,
4 CASE
5 WHEN dbms_lob.INSTR(m.ABCDETAIL,'ABC$$') = 0
6 THEN ''
7 ELSE dbms_lob.SUBSTR(m.ABCDETAIL,dbms_lob.INSTR(m.ABCDETAIL,'##AAA')-
8 dbms_lob.INSTR(m.ABCDETAIL,'ABC$$')-10,
9 dbms_lob.INSTR(m.ABCDETAIL,'ABC')+10)
10 END AS SOMECALC
11 FROM MYTABLE m
12 WHERE m.ABC = 1
13 AND ROWNUM < 1000
14 ) a
15 WHERE a.SOMECALC LIKE '%AAA%';
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 76631248
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 4056 | 2 (0)| 00:00:01 |
|* 1 | VIEW | | 1 | 4056 | 2 (0)| 00:00:01 |
|* 2 | COUNT STOPKEY | | | | | |
|* 3 | TABLE ACCESS FULL| MYTABLE | 1 | 2054 | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("A"."SOMECALC" LIKE '%AAA%' AND "A"."SOMECALC" IS NOT
NULL)
2 - filter(ROWNUM<1000)
3 - filter("M"."ABC"=1)
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
您在解释计划中看到 COUNT STOPKEY ,这是因为 ROWNUM 用于过滤行。因此,在第一个解释计划中,首先应用STOPKEY
,然后在第二个查询中应用filter("A"."SOMECALC" LIKE '%AAA%' AND "A"."SOMECALC" IS NOT
NULL).