一美女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优化高手了。