您的位置:首页 > 数据库 > Oracle

oracle in,exists,not in,not exists

2014-09-17 20:10 435 查看
--在in和exists中,oracle可以把父查询推进到子查询

SQL> SELECT COUNT(*)

  2    FROM T0 LT

  3   WHERE  EXISTS (SELECT NULL FROM T1 LA WHERE LA.T1_ID = LT.T0_ID)

  4     AND LT.T0_ID IN (10000,10001,10002,10003,10004,10005,10006,10007,10008,10009,10010,10011,10012,10013,10014,10015,10016);

  COUNT(*)

----------

        17

已用时间:  00: 00: 00.39

执行计划

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

Plan hash value: 2619996249

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

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

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

|   0 | SELECT STATEMENT     |                            |     1 |    10 |    20   (5)| 00:00:01 |

|   1 |  SORT AGGREGATE      |                            |     1 |    10 |            |          |

|   2 |   NESTED LOOPS       |                            |     1 |    10 |    20   (5)| 00:00:01 |

|   3 |    SORT UNIQUE       |                            |  3382 | 16910 |    19   (0)| 00:00:01 |

|   4 |     INLIST ITERATOR  |                            |       |       |            |          |

|*  5 |      INDEX RANGE SCAN| T1_IDX |  3382 | 16910 |    19   (0)| 00:00:01 |

|*  6 |    INDEX UNIQUE SCAN | T0_PK             |     1 |     5 |     0   (0)| 00:00:01 |

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

Predicate Information (identified by operation id):

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

   5 - access("LA"."T1_ID"=10000 OR "LA"."T1_ID"=10001 OR

              "LA"."T1_ID"=10002 OR "LA"."T1_ID"=10003 OR

              "LA"."T1_ID"=10004 OR "LA"."T1_ID"=10005 OR

              "LA"."T1_ID"=10006 OR "LA"."T1_ID"=10007 OR

              "LA"."T1_ID"=10008 OR "LA"."T1_ID"=10009 OR

              "LA"."T1_ID"=10010 OR "LA"."T1_ID"=10011 OR

              "LA"."T1_ID"=10012 OR "LA"."T1_ID"=10013 OR

              "LA"."T1_ID"=10014 OR "LA"."T1_ID"=10015 OR

              "LA"."T1_ID"=10016)

   6 - access("LA"."T1_ID"="LT"."T0_ID")

       filter("LT"."T0_ID"=10000 OR "LT"."T0_ID"=10001 OR "LT"."T0_ID"=10002 OR

              "LT"."T0_ID"=10003 OR "LT"."T0_ID"=10004 OR "LT"."T0_ID"=10005 OR

              "LT"."T0_ID"=10006 OR "LT"."T0_ID"=10007 OR "LT"."T0_ID"=10008 OR

              "LT"."T0_ID"=10009 OR "LT"."T0_ID"=10010 OR "LT"."T0_ID"=10011 OR

              "LT"."T0_ID"=10012 OR "LT"."T0_ID"=10013 OR "LT"."T0_ID"=10014 OR

              "LT"."T0_ID"=10015 OR "LT"."T0_ID"=10016)

统计信息

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

          0  recursive calls

          0  db block gets

         34  consistent gets

          0  physical reads

          0  redo size

        354  bytes sent via SQL*Net to client

        476  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          1  sorts (memory)

          0  sorts (disk)

          1  rows processed
 
 

SQL> SELECT COUNT(*)

  2    FROM T0 LT

  3   WHERE LT.T0_ID IN (SELECT LA.T1_ID FROM T1 LA)

  4     AND LT.T0_ID IN (10000,10001,10002,10003,10004,10005,10006,10007,10008,10009,10010,10011,10012,10013,10014,10015,10016);

  COUNT(*)

----------

        17

已用时间:  00: 00: 00.39

执行计划

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

Plan hash value: 2619996249

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

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

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

|   0 | SELECT STATEMENT     |                            |     1 |    10 |    20   (5)| 00:00:01 |

|   1 |  SORT AGGREGATE      |                            |     1 |    10 |            |          |

|   2 |   NESTED LOOPS       |                            |     1 |    10 |    20   (5)| 00:00:01 |

|   3 |    SORT UNIQUE       |                            |  3382 | 16910 |    19   (0)| 00:00:01 |

|   4 |     INLIST ITERATOR  |                            |       |       |            |          |

|*  5 |      INDEX RANGE SCAN| T1_IDX |  3382 | 16910 |    19   (0)| 00:00:01 |

|*  6 |    INDEX UNIQUE SCAN | T0_PK             |     1 |     5 |     0   (0)| 00:00:01 |

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

Predicate Information (identified by operation id):

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

   5 - access("LA"."T1_ID"=10000 OR "LA"."T1_ID"=10001 OR

              "LA"."T1_ID"=10002 OR "LA"."T1_ID"=10003 OR

              "LA"."T1_ID"=10004 OR "LA"."T1_ID"=10005 OR

              "LA"."T1_ID"=10006 OR "LA"."T1_ID"=10007 OR

              "LA"."T1_ID"=10008 OR "LA"."T1_ID"=10009 OR

              "LA"."T1_ID"=10010 OR "LA"."T1_ID"=10011 OR

              "LA"."T1_ID"=10012 OR "LA"."T1_ID"=10013 OR

              "LA"."T1_ID"=10014 OR "LA"."T1_ID"=10015 OR

              "LA"."T1_ID"=10016)

   6 - access("LT"."T0_ID"="LA"."T1_ID")

       filter("LT"."T0_ID"=10000 OR "LT"."T0_ID"=10001 OR "LT"."T0_ID"=10002 OR

              "LT"."T0_ID"=10003 OR "LT"."T0_ID"=10004 OR "LT"."T0_ID"=10005 OR

              "LT"."T0_ID"=10006 OR "LT"."T0_ID"=10007 OR "LT"."T0_ID"=10008 OR

              "LT"."T0_ID"=10009 OR "LT"."T0_ID"=10010 OR "LT"."T0_ID"=10011 OR

              "LT"."T0_ID"=10012 OR "LT"."T0_ID"=10013 OR "LT"."T0_ID"=10014 OR

              "LT"."T0_ID"=10015 OR "LT"."T0_ID"=10016)

统计信息

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

          0  recursive calls

          0  db block gets

         34  consistent gets

          0  physical reads

          0  redo size

        354  bytes sent via SQL*Net to client

        476  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          1  sorts (memory)

          0  sorts (disk)

          1  rows processed

--从以上查询可知在in,exits,oracle可以把查询条件推进到子查询中,进而可以使用索引
 

SQL> SELECT COUNT(*)

  2    FROM T0 LT

  3   WHERE LT.T0_ID NOT IN (SELECT LA.T1_ID FROM T1 LA)

  4     AND LT.T0_ID IN (10000,10001,10002,10003,10004,10005,10006,10007,10008,10009,10010,10011,10012,10013,10014,10015,10016);

  COUNT(*)

----------

         0

已用时间:  00: 00: 01.83

执行计划

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

Plan hash value: 1672357812

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

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

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

|   0 | SELECT STATEMENT        |                            |     1 |    10 | 14768   (1)| 00:02:58 |       |       |

|   1 |  SORT AGGREGATE         |                            |     1 |    10 |            |          |       |       |

|*  2 |   FILTER                |                            |       |       |            |          |       |       |

|   3 |    NESTED LOOPS ANTI SNA|                            |     1 |    10 | 14768 (100)| 00:02:58 |       |       |

|   4 |     INLIST ITERATOR     |                            |       |       |            |          |       |       |

|*  5 |      INDEX UNIQUE SCAN  | T0_PK             |    17 |    85 |    15   (0)| 00:00:01 |       |       |

|*  6 |     INDEX RANGE SCAN    | T1_IDX |  7512K|    35M|     2   (0)| 00:00:01 |       |       |

|   7 |    PARTITION RANGE ALL  |                            |     1 |     5 | 14736   (1)| 00:02:57 |     1 |     6 |

|*  8 |     TABLE ACCESS FULL   | T1          |     1 |     5 | 14736   (1)| 00:02:57 |     1 |     6 |

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

Predicate Information (identified by operation id):

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

   2 - filter( NOT EXISTS (SELECT 0 FROM "T1" "LA" WHERE "LA"."T1_ID" IS NULL))

   5 - access("LT"."T0_ID"=10000 OR "LT"."T0_ID"=10001 OR "LT"."T0_ID"=10002 OR "LT"."T0_ID"=10003 OR

              "LT"."T0_ID"=10004 OR "LT"."T0_ID"=10005 OR "LT"."T0_ID"=10006 OR "LT"."T0_ID"=10007 OR

              "LT"."T0_ID"=10008 OR "LT"."T0_ID"=10009 OR "LT"."T0_ID"=10010 OR "LT"."T0_ID"=10011 OR

              "LT"."T0_ID"=10012 OR "LT"."T0_ID"=10013 OR "LT"."T0_ID"=10014 OR "LT"."T0_ID"=10015 OR

              "LT"."T0_ID"=10016)

   6 - access("LT"."T0_ID"="LA"."T1_ID")

   8 - filter("LA"."T1_ID" IS NULL)

统计信息

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

          0  recursive calls

          0  db block gets

      53595  consistent gets

          0  physical reads

          0  redo size

        353  bytes sent via SQL*Net to client

        476  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          1  rows processed

 

SQL> SELECT COUNT(*)

  2    FROM T0 LT

  3   WHERE  NOT EXISTS (SELECT NULL FROM T1 LA WHERE LA.T1_ID = LT.T0_ID)

  4     AND LT.T0_ID IN (10000,10001,10002,10003,10004,10005,10006,10007,10008,10009,10010,10011,10012,10013,10014,10015,10016);

  COUNT(*)

----------

         0

已用时间:  00: 00: 00.39

执行计划

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

Plan hash value: 4283638437

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

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

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

|   0 | SELECT STATEMENT     |                            |     1 |    10 |    34   (0)| 00:00:01 |

|   1 |  SORT AGGREGATE      |                            |     1 |    10 |            |          |

|*  2 |   HASH JOIN ANTI     |                            |     1 |    10 |    34   (0)| 00:00:01 |

|   3 |    INLIST ITERATOR   |                            |       |       |            |          |

|*  4 |     INDEX UNIQUE SCAN| T0_PK             |    17 |    85 |    15   (0)| 00:00:01 |

|   5 |    INLIST ITERATOR   |                            |       |       |            |          |

|*  6 |     INDEX RANGE SCAN | T1_IDX |  3382 | 16910 |    19   (0)| 00:00:01 |

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

Predicate Information (identified by operation id):

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

   2 - access("LA"."T1_ID"="LT"."T0_ID")

   4 - access("LT"."T0_ID"=10000 OR "LT"."T0_ID"=10001 OR "LT"."T0_ID"=10002 OR

              "LT"."T0_ID"=10003 OR "LT"."T0_ID"=10004 OR "LT"."T0_ID"=10005 OR

              "LT"."T0_ID"=10006 OR "LT"."T0_ID"=10007 OR "LT"."T0_ID"=10008 OR

              "LT"."T0_ID"=10009 OR "LT"."T0_ID"=10010 OR "LT"."T0_ID"=10011 OR

              "LT"."T0_ID"=10012 OR "LT"."T0_ID"=10013 OR "LT"."T0_ID"=10014 OR

              "LT"."T0_ID"=10015 OR "LT"."T0_ID"=10016)

   6 - access("LA"."T1_ID"=10000 OR "LA"."T1_ID"=10001 OR

              "LA"."T1_ID"=10002 OR "LA"."T1_ID"=10003 OR

              "LA"."T1_ID"=10004 OR "LA"."T1_ID"=10005 OR

              "LA"."T1_ID"=10006 OR "LA"."T1_ID"=10007 OR

              "LA"."T1_ID"=10008 OR "LA"."T1_ID"=10009 OR

              "LA"."T1_ID"=10010 OR "LA"."T1_ID"=10011 OR

              "LA"."T1_ID"=10012 OR "LA"."T1_ID"=10013 OR

              "LA"."T1_ID"=10014 OR "LA"."T1_ID"=10015 OR

              "LA"."T1_ID"=10016)

统计信息

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

          0  recursive calls

          0  db block gets

         34  consistent gets

          0  physical reads

          0  redo size

        353  bytes sent via SQL*Net to client

        476  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          1  rows processed

--对于not in,oracle不可以把子查询推进到子查询中,进而走了全表扫描

--对于not exists,oracle可以把父查询推进到子查询,进而走索引

--所以如果子查询表很大时not exists较not in好,如果子查询表很少,则反之
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: