您的位置:首页 > 数据库

和美女边扯淡边优化SQL

2012-05-18 16:11 316 查看
一美女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优化高手了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: