查看: 6547|回复: 12

[讨论] 关于oracle的<>

[复制链接]
pwangeng 该用户已被删除
跳转到指定楼层
1#
发表于 2010-7-15 11:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
看到一则oracle优化的例子,关于<>的,但不理解为何
平常用<>都是直接用 “字段<>值”的方式的,但看到奇怪的用法确是:“字段<值 or 字段>值”这样的方式
而且前者能用不到索引,而后者确用到了。这个是<>的特殊用法还是什么呢?

--测试数据
--创建大表
create table big_table
as
select rownum id, a.*
  from all_objects a
where 1=0
/
alter table big_table nologging;

declare
    l_cnt number;
    l_rows number := &1;
begin
    insert /*+ append */
    into big_table
    select rownum, a.*
      from all_objects a
   where rownum <= &1;

    l_cnt := sql%rowcount;

    commit;

    while (l_cnt < l_rows)
    loop
        insert /*+ APPEND */ into big_table
        select rownum+l_cnt,
               OWNER, OBJECT_NAME, SUBOBJECT_NAME,
               OBJECT_ID, DATA_OBJECT_ID,
               OBJECT_TYPE, CREATED, LAST_DDL_TIME,
               TIMESTAMP, STATUS, TEMPORARY,
               GENERATED, SECONDARY
          from big_table
         where rownum <= l_rows-l_cnt;
        l_cnt := l_cnt + sql%rowcount;
        commit;
    end loop;
end;
/

alter table big_table add constraint
big_table_pk primary key(id)
/

select count(*) from big_table;
/*
Connected to Oracle9i Enterprise Edition Release 9.2.0.1.0
Connected as scott

SQL>

Table created

Table altered

PL/SQL procedure successfully completed

Table altered

  COUNT(*)
----------
    100000

SQL>
*/


select * from big_table where id<>100000;
--Explain Plan(全表扫描)
/*
SELECT STATEMENT, GOAL = CHOOSE        0                                                               
TABLE ACCESS FULL        1        FULL        SCOTT        BIG_TABLE                                       
*/

select * from big_table where id<100000 or id>100000;
--Explain Plan(使用索引)
/*
SELECT STATEMENT, GOAL = CHOOSE        0                                                               
CONCATENATION        1                                                               
  TABLE ACCESS BY INDEX ROWID        2        BY INDEX ROWID        SCOTT        BIG_TABLE                                       
   INDEX RANGE SCAN        3        RANGE SCAN        SCOTT        BIG_TABLE_PK                                       
  TABLE ACCESS BY INDEX ROWID        4        BY INDEX ROWID        SCOTT        BIG_TABLE                                       
   INDEX RANGE SCAN        5        RANGE SCAN        SCOTT        BIG_TABLE_PK                                       
*/
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
2#
发表于 2010-7-15 11:08 | 只看该作者
本来就不是同一个东西啊

使用道具 举报

回复
pwangeng 该用户已被删除
3#
 楼主| 发表于 2010-7-15 11:17 | 只看该作者
是不是只要<>作用在where子句的索引字段上就不会使用该索引了呢?

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
4#
发表于 2010-7-15 12:11 | 只看该作者
以前记得哪里说or 也不能用index...看来不是的

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
5#
发表于 2010-7-15 12:19 | 只看该作者
<>可能用到index的,但是不一定你想要的index,比如full index

使用道具 举报

回复
论坛徽章:
25
奥运会纪念徽章:射击
日期:2013-01-28 09:12:182014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11马上有车
日期:2014-03-20 16:13:24马上有房
日期:2014-03-20 16:14:11马上有钱
日期:2014-03-20 16:14:11马上有对象
日期:2014-03-20 16:14:11马上加薪
日期:2014-03-20 16:14:11喜羊羊
日期:2015-04-09 18:46:34秀才
日期:2016-03-24 09:20:52
6#
发表于 2010-7-15 15:44 | 只看该作者
原帖由 dingjun123 于 2010-7-15 11:08 发表
本来就不是同一个东西啊


的确不是同一个东西,一个不不等于10000的,一个走区间的,虽然结果一样,可是不一样的表达,索引不知道什么东西不存在,却知道给你要的哪个范围的数据。

使用道具 举报

回复
招聘 : 数据库管理员
论坛徽章:
9
生肖徽章2007版:牛
日期:2009-03-10 21:26:492010新春纪念徽章
日期:2010-01-04 08:33:082010年世界杯参赛球队:葡萄牙
日期:2010-02-22 14:35:242010新春纪念徽章
日期:2010-03-01 11:19:092010广州亚运会纪念徽章:射击
日期:2010-09-08 23:42:12ITPUB9周年纪念徽章
日期:2010-10-08 09:31:212010广州亚运会纪念徽章:拳击
日期:2010-10-30 00:46:582011新春纪念徽章
日期:2011-02-18 11:43:322011新春纪念徽章
日期:2011-03-01 08:49:39
7#
发表于 2010-7-16 09:07 | 只看该作者
原帖由 dingjun123 于 2010-7-15 12:19 发表
可能用到index的,但是不一定你想要的index,比如full index


不是很理解,能否举个例子呢?

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
8#
发表于 2010-7-16 09:20 | 只看该作者
你可以造个单列的表试试看,然后建个索引,select语句中我测试了<>是走full index scan的,其他语句没有试验

使用道具 举报

回复
论坛徽章:
32
奥运会纪念徽章:摔跤
日期:2012-08-23 11:03:05青年奥林匹克运动会-击剑
日期:2014-09-19 10:58:152014年世界杯参赛球队:巴西
日期:2014-07-07 12:19:232014年世界杯参赛球队: 瑞士
日期:2014-05-19 12:18:36马上有钱
日期:2014-04-08 12:12:232014年新春福章
日期:2014-04-04 14:20:47马上有钱
日期:2014-02-18 16:43:092014年新春福章
日期:2014-02-18 16:43:09红旗
日期:2014-02-14 15:15:55优秀写手
日期:2013-12-18 09:29:16
9#
发表于 2010-7-17 13:21 | 只看该作者
SQL> create table t_test_notequ1
  2  as select * from dba_objects ;

表已创建。

SQL>
SQL> create index idx_test_notequ1 on t_test_notequ1 (object_id);

索引已创建。

SQL> set autot on;
SQL> select count(*) from t_test_notequ1 a where a.object_id <> 1;

  COUNT(*)
----------
     59622


执行计划
----------------------------------------------------------
Plan hash value: 2434651730

-------------------------------------------------------------------------------

----------

| Id  | Operation             | Name             | Rows  | Bytes | Cost (%CPU)|
Time     |

-------------------------------------------------------------------------------

----------

|   0 | SELECT STATEMENT      |                  |     1 |    13 |    33   (7)|
00:00:01 |

|   1 |  SORT AGGREGATE       |                  |     1 |    13 |            |
         |

|*  2 |   INDEX FAST FULL SCAN| IDX_TEST_NOTEQU1 | 60125 |   763K|    33   (7)|
00:00:01 |

-------------------------------------------------------------------------------

----------


Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("A"."OBJECT_ID"<>1)

Note
-----
   - dynamic sampling used for this statement


统计信息
----------------------------------------------------------
        199  recursive calls
          0  db block gets
        235  consistent gets
        320  physical reads
          0  redo size
        410  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          3  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>

使用道具 举报

回复
论坛徽章:
32
奥运会纪念徽章:摔跤
日期:2012-08-23 11:03:05青年奥林匹克运动会-击剑
日期:2014-09-19 10:58:152014年世界杯参赛球队:巴西
日期:2014-07-07 12:19:232014年世界杯参赛球队: 瑞士
日期:2014-05-19 12:18:36马上有钱
日期:2014-04-08 12:12:232014年新春福章
日期:2014-04-04 14:20:47马上有钱
日期:2014-02-18 16:43:092014年新春福章
日期:2014-02-18 16:43:09红旗
日期:2014-02-14 15:15:55优秀写手
日期:2013-12-18 09:29:16
10#
发表于 2010-7-17 13:22 | 只看该作者
SQL> update t_test_notequ1 a set a.object_id = 2 where a.object_id <> 1;

已更新59622行。


执行计划
----------------------------------------------------------
Plan hash value: 2339249418

--------------------------------------------------------------------------------

-----

| Id  | Operation          | Name           | Rows  | Bytes | Cost (%CPU)| Time
    |

--------------------------------------------------------------------------------

-----

|   0 | UPDATE STATEMENT   |                | 60125 |   763K|   184   (3)| 00:00

:03 |

|   1 |  UPDATE            | T_TEST_NOTEQU1 |       |       |            |
    |

|*  2 |   TABLE ACCESS FULL| T_TEST_NOTEQU1 | 60125 |   763K|   184   (3)| 00:00

:03 |

--------------------------------------------------------------------------------

-----


Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("A"."OBJECT_ID"<>1)

Note
-----
   - dynamic sampling used for this statement


统计信息
----------------------------------------------------------
        410  recursive calls
      67022  db block gets
       1083  consistent gets
        301  physical reads
   21311844  redo size
        673  bytes sent via SQL*Net to client
        605  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          6  sorts (memory)
          0  sorts (disk)
      59622  rows processed

SQL>

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表