ITPub博客

首页 > 数据库 > Oracle > [20170420]表达式加0或者减0不一样.txt

[20170420]表达式加0或者减0不一样.txt

原创 Oracle 作者:lfree 时间:2017-04-20 09:41:55 0 删除 编辑

[20170420]表达式加0或者减0不一样.txt

--//oracle 有时候避免某个索引采用字段+0或者-0的方式,不使用索引,但是两者存在一点点区别,通过例子说明。

1.环境:
SCOTT@book> @ &r/ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

SCOTT@book> create table t as select rownum id1,round(rownum/50,0) id2,lpad('x',100,'x') name from dual connect by level <=4e5;
Table created.

execute sys.dbms_stats.gather_table_stats ( OwnName => user),TabName => 't',Estimate_Percent => NULL,Method_Opt => 'FOR ALL COLUMNS SIZE 1 ',Cascade => True ,No_Invalidate => false)

2.测试:
SCOTT@book> select count(*) from t where id2=100;
  COUNT(*)
----------
        50

Plan hash value: 2966233522

------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers | Reads  |
------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |       |  1782 (100)|          |      1 |00:00:00.04 |    6449 |   6446 |
|   1 |  SORT AGGREGATE    |      |      1 |      1 |     4 |            |          |      1 |00:00:00.04 |    6449 |   6446 |
|*  2 |   TABLE ACCESS FULL| T    |      1 |     50 |   200 |  1782   (1)| 00:00:22 |     50 |00:00:00.04 |    6449 |   6446 |
------------------------------------------------------------------------------------------------------------------------------

SCOTT@book> select count(*) from t where id2+0=100;
  COUNT(*)
----------
        50

Plan hash value: 2966233522
------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers | Reads  |
------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |       |  1782 (100)|          |      1 |00:00:00.07 |    6449 |   6446 |
|   1 |  SORT AGGREGATE    |      |      1 |      1 |     4 |            |          |      1 |00:00:00.07 |    6449 |   6446 |
|*  2 |   TABLE ACCESS FULL| T    |      1 |     50 |   200 |  1782   (1)| 00:00:22 |     50 |00:00:00.07 |    6449 |   6446 |
------------------------------------------------------------------------------------------------------------------------------

SCOTT@book> select count(*) from t where id2-0=100;
  COUNT(*)
----------
        50
Plan hash value: 2966233522
------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers | Reads  |
------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |       |  1782 (100)|          |      1 |00:00:00.08 |    6449 |   6446 |
|   1 |  SORT AGGREGATE    |      |      1 |      1 |     4 |            |          |      1 |00:00:00.08 |    6449 |   6446 |
|*  2 |   TABLE ACCESS FULL| T    |      1 |   4000 | 16000 |  1782   (1)| 00:00:22 |     50 |00:00:00.08 |    6449 |   6446 |
------------------------------------------------------------------------------------------------------------------------------

3.分析我这里没有建立索引在字段ID2上,执行计划选择全表扫描,但是你如果仔细看E-Rows就可以看出几种的区别。

id2=100    E-Rows 50
id2+0=100  E-Rows 50
id2-0=100  E-Rows 4000

--//很明显oracle在分析生成执行计划上+0,-0是区别对待的,采用+0方式,oracle视乎知道执行者选择绕过索引(当然我没建立),估算E-Rows的统计信息是正确的。
--//而采用-0方式,oracle把这样的表达式当作函数对待,按照1%取E_rows ,400000*0.01=4000。
--//知道这个没什么意思,只是提醒自己要注意一些细节。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-2137658/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    4006
  • 访问量
    7971214