和美女邊扯淡邊優化SQL

一美女DBA想學SQL優化,經常和俺扯淡,俺也樂於扯淡。俺最喜歡美女了。今天他發來一個SQL叫俺幫忙看看。

執行計劃如下:

SELECT "A1"."CODE", "A1"."DEVICE_ID", "A1"."SIDEB_PORT_ID", "A1"."VERSION"
  FROM (SELECT 
         "A2"."CODE" "CODE",
         "A2"."DEVICE_ID" "DEVICE_ID",
         "A2"."SIDEB_PORT_ID" "SIDEB_PORT_ID",
         "A3"."VERSION" "VERSION",
         ROW_NUMBER() OVER(PARTITION BY "A4"."PROD_ID" ORDER BY "A4"."HIST_TIME" DESC) "RN"
          FROM "RM"."H_PROD_2_RF_SERV"            "A4",
               "RM"."H_RSC_FACING_SERV_LINE_ITEM" "A3",
               "RM"."CONNECTOR"                   "A2"
         WHERE "A4"."SERV_ID" = "A3"."SERV_ID"
           AND "A3"."LINE_ID" = "A2"."CONNECTOR_ID"
           AND EXISTS (SELECT 0
                  FROM "RM"."DEVICE_ITEM" "A5"
                 WHERE "A5"."DEVICE_ID" = "A2"."DEVICE_ID"
                   AND "A5"."ITEM_SPEC_ID" = 200006
                   AND "A5"."VALUE" ='7')
           AND "A4"."PROD_ID" = 313) "A1"
 WHERE "A1"."RN" = 1
 -----9.437秒

48194511行 A5
35467304行 A2



Execution Plan
----------------------------------------------------------
Plan hash value: 10111536

-----------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name                        | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                             |     1 |   175 |    20  (10)| 00:00:01 |
|*  1 |  VIEW                             |                             |     1 |   175 |    20  (10)| 00:00:01 |
|*  2 |   WINDOW SORT PUSHED RANK         |                             |     1 |   109 |    20  (10)| 00:00:01 |
|   3 |    NESTED LOOPS                   |                             |     1 |   109 |    19   (6)| 00:00:01 |
|   4 |     NESTED LOOPS                  |                             |     1 |    80 |    17   (6)| 00:00:01 |
|   5 |      MERGE JOIN CARTESIAN         |                             |     1 |    60 |    13   (8)| 00:00:01 |
|   6 |       SORT UNIQUE                 |                             |     1 |    36 |     6   (0)| 00:00:01 |
|*  7 |        TABLE ACCESS BY INDEX ROWID| DEVICE_ITEM                 |     1 |    36 |     6   (0)| 00:00:01 |
|*  8 |         INDEX RANGE SCAN          | IDX_DEVICE_ITEM_VALE        |     9 |       |     4   (0)| 00:00:01 |
|   9 |       BUFFER SORT                 |                             |     4 |    96 |     7  (15)| 00:00:01 |
|  10 |        TABLE ACCESS BY INDEX ROWID| H_PROD_2_RF_SERV            |     4 |    96 |     6   (0)| 00:00:01 |
|* 11 |         INDEX RANGE SCAN          | IDX_HP2RS_PRODID_SERVID     |     4 |       |     2   (0)| 00:00:01 |
|  12 |      TABLE ACCESS BY INDEX ROWID  | H_RSC_FACING_SERV_LINE_ITEM |     2 |    40 |     4   (0)| 00:00:01 |
|* 13 |       INDEX RANGE SCAN            | IDX_HRFSLI_SERV             |     2 |       |     2   (0)| 00:00:01 |
|* 14 |     TABLE ACCESS BY INDEX ROWID   | CONNECTOR                   |     1 |    29 |     2   (0)| 00:00:01 |
|* 15 |      INDEX UNIQUE SCAN            | PK_CONNECTOR                |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------------

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

   1 - filter("A1"."RN"=1)
   2 - filter(ROW_NUMBER() OVER ( PARTITION BY "A4"."PROD_ID" ORDER BY
              INTERNAL_FUNCTION("A4"."HIST_TIME") DESC )<=1)
   7 - filter("A5"."ITEM_SPEC_ID"=200006)
   8 - access("A5"."VALUE"='7')
  11 - access("A4"."PROD_ID"=313)
  13 - access("A4"."SERV_ID"="A3"."SERV_ID")
  14 - filter("A5"."DEVICE_ID"="A2"."DEVICE_ID")
  15 - access("A3"."LINE_ID"="A2"."CONNECTOR_ID")


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
    2539920  consistent gets
          0  physical reads
          0  redo size
        735  bytes sent via SQL*Net to client
        492  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          3  sorts (memory)
          0  sorts (disk)
          1  rows processed

 

落落 14:56:39
SELECT COUNT(*)
          FROM "RM"."DEVICE_ITEM" "A5"
         WHERE "A5"."ITEM_SPEC_ID" = 200006
           AND "A5"."VALUE" = '7'
落落 14:56:44
看哈 返回結果
美女QQ 14:58:02

  COUNT(*)
----------
     68384
落落 15:20:15
select count(*) from H_PROD_2_RF_SERV
where prod_id=313 ;
落落 15:20:18
給出返回結果
美女QQ 15:21:24
正在跑
落落 15:24:03
還沒出結果啊。。
美女QQ 15:24:24
select count(*) from rm.H_PROD_2_RF_SERV;

  COUNT(*)
----------
  17036077
 
美女QQ 15:24:25
ok
美女QQ 15:24:36
額!錯了 
美女QQ 15:24:38
等下
美女QQ 15:24:51 
  select count(*) from rm.H_PROD_2_RF_SERV  where prod_id=313 ;

  COUNT(*)
----------
         6
美女QQ 15:24:56
這個正確

落落 15:33:20
SELECT "A1"."CODE", "A1"."DEVICE_ID", "A1"."SIDEB_PORT_ID", "A1"."VERSION"
  FROM (SELECT /*+ use_nl(a4,a3) leading(a4) use_nl(a3,a2) use_hash(a5) */
         "A2"."CODE" "CODE",
         "A2"."DEVICE_ID" "DEVICE_ID",
         "A2"."SIDEB_PORT_ID" "SIDEB_PORT_ID",
         "A3"."VERSION" "VERSION",
         ROW_NUMBER() OVER(PARTITION BY "A4"."PROD_ID" ORDER BY "A4"."HIST_TIME" DESC) "RN"
          FROM "RM"."H_PROD_2_RF_SERV"            "A4",
               "RM"."H_RSC_FACING_SERV_LINE_ITEM" "A3",
               "RM"."CONNECTOR"                   "A2"
         WHERE "A4"."SERV_ID" = "A3"."SERV_ID"
           AND "A3"."LINE_ID" = "A2"."CONNECTOR_ID"
           AND EXISTS (SELECT 0
                  FROM "RM"."DEVICE_ITEM" "A5"
                 WHERE "A5"."DEVICE_ID" = "A2"."DEVICE_ID"
                   AND "A5"."ITEM_SPEC_ID" = 200006
                   AND "A5"."VALUE" ='7')
           AND "A4"."PROD_ID" = 313) "A1"
 WHERE "A1"."RN" = 1
 
美女QQ 15:33:42
努力成功了!我剛剛在生產庫上面測試,0.188秒

下面是優化之後的執行計劃

15:50:13 SQL> SELECT "A1"."CODE", "A1"."DEVICE_ID", "A1"."SIDEB_PORT_ID", "A1"."VERSION"
15:50:14   2    FROM (SELECT /*+ use_nl(a4,a3) leading(a4) use_nl(a3,a2) use_hash(a5) */
15:50:14   3           "A2"."CODE" "CODE",
15:50:14   4           "A2"."DEVICE_ID" "DEVICE_ID",
15:50:14   5           "A2"."SIDEB_PORT_ID" "SIDEB_PORT_ID",
15:50:14   6           "A3"."VERSION" "VERSION",
15:50:14   7           ROW_NUMBER() OVER(PARTITION BY "A4"."PROD_ID" ORDER BY "A4"."HIST_TIME" DESC) "RN"
15:50:14   8            FROM "RM"."H_PROD_2_RF_SERV"            "A4",
15:50:14   9                 "RM"."H_RSC_FACING_SERV_LINE_ITEM" "A3",
15:50:14  10                 "RM"."CONNECTOR"                   "A2"
15:50:14  11           WHERE "A4"."SERV_ID" = "A3"."SERV_ID"
15:50:14  12             AND "A3"."LINE_ID" = "A2"."CONNECTOR_ID"
15:50:14  13             AND EXISTS (SELECT 0
15:50:14  14                    FROM "RM"."DEVICE_ITEM" "A5"
15:50:14  15                   WHERE "A5"."DEVICE_ID" = "A2"."DEVICE_ID"
15:50:14  16                     AND "A5"."ITEM_SPEC_ID" = 200006
15:50:14  17                     AND "A5"."VALUE" ='7')
15:50:14  18             AND "A4"."PROD_ID" = 313) "A1"
15:50:14  19   WHERE "A1"."RN" = 1
15:50:15  20  ;


Execution Plan
----------------------------------------------------------
Plan hash value: 3121894527

----------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name                        | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                             |     1 |   175 |    40   (3)| 00:00:01 |
|*  1 |  VIEW                            |                             |     1 |   175 |    40   (3)| 00:00:01 |
|*  2 |   WINDOW SORT PUSHED RANK        |                             |     1 |   109 |    40   (3)| 00:00:01 |
|*  3 |    HASH JOIN SEMI                |                             |     1 |   109 |    39   (0)| 00:00:01 |
|   4 |     NESTED LOOPS                 |                             |     7 |   511 |    33   (0)| 00:00:01 |
|   5 |      NESTED LOOPS                |                             |     7 |   308 |    19   (0)| 00:00:01 |
|   6 |       TABLE ACCESS BY INDEX ROWID| H_PROD_2_RF_SERV            |     4 |    96 |     7   (0)| 00:00:01 |
|*  7 |        INDEX RANGE SCAN          | IDX_HP2RS_PRODID_SERVID     |     4 |       |     3   (0)| 00:00:01 |
|   8 |       TABLE ACCESS BY INDEX ROWID| H_RSC_FACING_SERV_LINE_ITEM |     2 |    40 |     4   (0)| 00:00:01 |
|*  9 |        INDEX RANGE SCAN          | IDX_HRFSLI_SERV             |     2 |       |     2   (0)| 00:00:01 |
|  10 |      TABLE ACCESS BY INDEX ROWID | CONNECTOR                   |     1 |    29 |     2   (0)| 00:00:01 |
|* 11 |       INDEX UNIQUE SCAN          | PK_CONNECTOR                |     1 |       |     1   (0)| 00:00:01 |
|* 12 |     TABLE ACCESS BY INDEX ROWID  | DEVICE_ITEM                 |     1 |    36 |     6   (0)| 00:00:01 |
|* 13 |      INDEX RANGE SCAN            | IDX_DEVICE_ITEM_VALE        |     9 |       |     4   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------

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

   1 - filter("A1"."RN"=1)
   2 - filter(ROW_NUMBER() OVER ( PARTITION BY "A4"."PROD_ID" ORDER BY
              INTERNAL_FUNCTION("A4"."HIST_TIME") DESC )<=1)
   3 - access("A5"."DEVICE_ID"="A2"."DEVICE_ID")
   7 - access("A4"."PROD_ID"=313)
   9 - access("A4"."SERV_ID"="A3"."SERV_ID")
  11 - access("A3"."LINE_ID"="A2"."CONNECTOR_ID")
  12 - filter("A5"."ITEM_SPEC_ID"=200006)
  13 - access("A5"."VALUE"='7')


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      14770  consistent gets
          0  physical reads
          0  redo size
        735  bytes sent via SQL*Net to client
        492  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed

如果你知道一個SQL應該走什麼樣的執行計劃,那麼你就是SQL優化高手了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章