我是Oracle數據庫的新手。 'select'語句會導致性能問題。問題是,象下面這樣:需要關於優化SQL select語句的幫助
聲明原件(工作非常慢):
SELECT *
FROM my_pos pos
WHERE my_source NOT IN
(SELECT my_source_id FROM my_source WHERE can_delete = 0
)
AND EXISTS
(SELECT 1
FROM my_agreement agr,
my_account acc,
my_account fund_acc,
my_client cli,
WHERE (agr.agr_client_acc_id = pos.my_acc_id
OR agr.agr_cp_acc_id = pos.my_acc_id
OR agr.agr_client_coll_acc_id = pos.my_acc_id
OR agr.agr_pool_acc_id = pos.my_acc_id
OR agr.client_pool_acc_id = pos.my_acc_id)
AND agr.agr_client_acc_id = acc.my_acc_id
AND acc.fund_acc_id = fund_acc.my_acc_id(+)
AND cli.client_id = (
CASE
WHEN fund_acc.my_acc_id IS NOT NULL
THEN fund_acc.client_id
ELSE acc.client_id
END)
);
解釋計劃爲聲明原文:
Plan hash value: 4147965473
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1748 | 290K| 2532 (4)| 00:00:31 |
|* 1 | HASH JOIN SEMI | | 1748 | 290K| 2532 (4)| 00:00:31 |
|* 2 | HASH JOIN RIGHT ANTI | | 1748 | 268K| 1364 (2)| 00:00:17 |
|* 3 | TABLE ACCESS FULL | MY_SOURCE | 44 | 264 | 2 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | MY_POS | 8738 | 1288K| 1361 (2)| 00:00:17 |
| 5 | VIEW | VW_SQ_1 | 16285 | 206K| 1167 (6)| 00:00:15 |
| 6 | UNION-ALL | | | | | |
| 7 | NESTED LOOPS | | 3257 | 78168 | 211 (7)| 00:00:03 |
|* 8 | HASH JOIN OUTER | | 3257 | 68397 | 209 (6)| 00:00:03 |
|* 9 | HASH JOIN | | 3257 | 45598 | 107 (6)| 00:00:02 |
| 10 | INDEX FAST FULL SCAN| IX_AGR_CLIENT | 3257 | 13028 | 4 (0)| 00:00:01 |
| 11 | TABLE ACCESS FULL | MY_ACCOUNT || 226K| 101 (4)| 00:00:02 |
| 12 | TABLE ACCESS FULL | MY_ACCOUNT || 158K| 100 (3)| 00:00:02 |
|* 13 | INDEX UNIQUE SCAN | PK_CLIENT | 1 | 3 | 0 (0)| 00:00:01 |
| 14 | NESTED LOOPS | | 3257 | 91196 | 238 (6)| 00:00:03 |
|* 15 | HASH JOIN OUTER | | 3257 | 81425 | 236 (5)| 00:00:03 |
|* 16 | HASH JOIN | | 3257 | 58626 | 135 (6)| 00:00:02 |
| 17 | TABLE ACCESS FULL | MY_AGREEMENT | 3257 | 26056 | 32 (4)| 00:00:01 |
| 18 | TABLE ACCESS FULL | MY_ACCOUNT || 226K| 101 (4)| 00:00:02 |
| 19 | TABLE ACCESS FULL | MY_ACCOUNT || 158K| 100 (3)| 00:00:02 |
|* 20 | INDEX UNIQUE SCAN | PK_CLIENT | 1 | 3 | 0 (0)| 00:00:01 |
| 21 | NESTED LOOPS | | 3257 | 84682 | 239 (6)| 00:00:03 |
|* 22 | HASH JOIN OUTER | | 3257 | 74911 | 236 (5)| 00:00:03 |
|* 23 | HASH JOIN | | 3257 | 52112 | 135 (6)| 00:00:02 |
| 24 | TABLE ACCESS FULL | MY_AGREEMENT | 3257 | 19542 | 32 (4)| 00:00:01 |
| 25 | TABLE ACCESS FULL | MY_ACCOUNT || 226K| 101 (4)| 00:00:02 |
| 26 | TABLE ACCESS FULL | MY_ACCOUNT || 158K| 100 (3)| 00:00:02 |
|* 27 | INDEX UNIQUE SCAN | PK_CLIENT | 1 | 3 | 0 (0)| 00:00:01 |
| 28 | NESTED LOOPS | | 3257 | 84682 | 239 (6)| 00:00:03 |
|* 29 | HASH JOIN OUTER | | 3257 | 74911 | 236 (5)| 00:00:03 |
|* 30 | HASH JOIN | | 3257 | 52112 | 135 (6)| 00:00:02 |
| 31 | TABLE ACCESS FULL | MY_AGREEMENT | 3257 | 19542 | 32 (4)| 00:00:01 |
| 32 | TABLE ACCESS FULL | MY_ACCOUNT || 226K| 101 (4)| 00:00:02 |
| 33 | TABLE ACCESS FULL | MY_ACCOUNT || 158K| 100 (3)| 00:00:02 |
|* 34 | INDEX UNIQUE SCAN | PK_CLIENT | 1 | 3 | 0 (0)| 00:00:01 |
| 35 | NESTED LOOPS | | 3257 | 84682 | 240 (7)| 00:00:03 |
|* 36 | HASH JOIN OUTER | | 3257 | 74911 | 237 (6)| 00:00:03 |
|* 37 | HASH JOIN | | 3257 | 52112 | 136 (6)| 00:00:02 |
| 38 | TABLE ACCESS FULL | MY_AGREEMENT | 3257 | 19542 | 33 (7)| 00:00:01 |
| 39 | TABLE ACCESS FULL | MY_ACCOUNT || 226K| 101 (4)| 00:00:02 |
| 40 | TABLE ACCESS FULL | MY_ACCOUNT || 158K| 100 (3)| 00:00:02 |
|* 41 | INDEX UNIQUE SCAN | PK_CLIENT | 1 | 3 | 0 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("VW_COL_1"="POS"."MY_ACC_ID")
2 - access("MY_SOURCE"="MY_SOURCE_ID")
3 - filter("CAN_DELETE"=0)
8 - access("ACC"."FUND_ACC_ID"="FUND_ACC"."MY_ACC_ID"(+))
9 - access("AGR"."AGR_CLIENT_ACC_ID"="ACC"."MY_ACC_ID")
13 - access("CLI"."CLIENT_ID"=CASE WHEN ("FUND_ACC"."MY_ACC_ID" IS NOT NULL)
THEN "FUND_ACC"."CLIENT_ID" ELSE "ACC"."CLIENT_ID" END)
15 - access("ACC"."FUND_ACC_ID"="FUND_ACC"."MY_ACC_ID"(+))
16 - access("AGR"."AGR_CLIENT_ACC_ID"="ACC"."MY_ACC_ID")
20 - access("CLI"."CLIENT_ID"=CASE WHEN ("FUND_ACC"."MY_ACC_ID" IS NOT NULL)
THEN "FUND_ACC"."CLIENT_ID" ELSE "ACC"."CLIENT_ID" END)
22 - access("ACC"."FUND_ACC_ID"="FUND_ACC"."MY_ACC_ID"(+))
23 - access("AGR"."AGR_CLIENT_ACC_ID"="ACC"."MY_ACC_ID")
27 - access("CLI"."CLIENT_ID"=CASE WHEN ("FUND_ACC"."MY_ACC_ID" IS NOT NULL)
THEN "FUND_ACC"."CLIENT_ID" ELSE "ACC"."CLIENT_ID" END)
29 - access("ACC"."FUND_ACC_ID"="FUND_ACC"."MY_ACC_ID"(+))
30 - access("AGR"."AGR_CLIENT_ACC_ID"="ACC"."MY_ACC_ID")
34 - access("CLI"."CLIENT_ID"=CASE WHEN ("FUND_ACC"."MY_ACC_ID" IS NOT NULL)
THEN "FUND_ACC"."CLIENT_ID" ELSE "ACC"."CLIENT_ID" END)
36 - access("ACC"."FUND_ACC_ID"="FUND_ACC"."MY_ACC_ID"(+))
37 - access("AGR"."AGR_CLIENT_ACC_ID"="ACC"."MY_ACC_ID")
41 - access("CLI"."CLIENT_ID"=CASE WHEN ("FUND_ACC"."MY_ACC_ID" IS NOT NULL)
THEN "FUND_ACC"."CLIENT_ID" ELSE "ACC"."CLIENT_ID" END)
新聲明(作品非常快):
SELECT *
FROM my_pos pos1
WHERE my_source NOT IN
(SELECT my_source_id FROM my_source WHERE can_delete = 0
)
AND EXISTS
(SELECT 1
FROM my_agreement agr,
my_account acc,
my_account fund_acc,
my_client cli,
-- add my_pos here
my_pos pos
WHERE (agr.agr_client_acc_id = pos.my_acc_id
OR agr.agr_cp_acc_id = pos.my_acc_id
OR agr.agr_client_coll_acc_id = pos.my_acc_id
OR agr.agr_pool_acc_id = pos.my_acc_id
OR agr.client_pool_acc_id = pos.my_acc_id)
AND agr.agr_client_acc_id = acc.my_acc_id
AND acc.fund_acc_id = fund_acc.my_acc_id(+)
AND cli.client_id = (
CASE
WHEN fund_acc.my_acc_id IS NOT NULL
THEN fund_acc.client_id
ELSE acc.client_id
END)
-- connect pos1 and pos
AND pos1.my_pos_id = pos.my_pos_id
);
新語句解釋計劃:
Plan hash value: 2962711282
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1748 | 290K| 9174 (2)| 00:01:51 |
|* 1 | HASH JOIN SEMI | | 1748 | 290K| 9174 (2)| 00:01:51 |
|* 2 | HASH JOIN RIGHT ANTI | | 1748 | 268K| 1364 (2)| 00:00:17 |
|* 3 | TABLE ACCESS FULL | MY_SOURCE | 44 | 264 | 2 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | MY_POS | 8738 | 1288K| 1361 (2)| 00:00:17 |
| 5 | VIEW | VW_SQ_1 | 32799 | 416K| 7809 (2)| 00:01:34 |
| 6 | CONCATENATION | | | | | |
|* 7 | HASH JOIN | | 1277 | 54911 | 1439 (2)| 00:00:18 |
| 8 | NESTED LOOPS | | 25 | 850 | 83 (3)| 00:00:01 |
| 9 | NESTED LOOPS OUTER | | 25 | 775 | 83 (3)| 00:00:01 |
| 10 | NESTED LOOPS | | 25 | 600 | 58 (4)| 00:00:01 |
|* 11 | TABLE ACCESS FULL | MY_AGREEMENT | 25 | 350 | 33 (7)| 00:00:01 |
| 12 | TABLE ACCESS BY INDEX ROWID| MY_ACCOUNT | 1 | 10 | 1 (0)| 00:00:01 |
|* 13 | INDEX UNIQUE SCAN | PK_MY_ACCOUNT | 1 | | 0 (0)| 00:00:01 |
| 14 | TABLE ACCESS BY INDEX ROWID | MY_ACCOUNT | 1 | 7 | 1 (0)| 00:00:01 |
|* 15 | INDEX UNIQUE SCAN | PK_MY_ACCOUNT | 1 | | 0 (0)| 00:00:01 |
|* 16 | INDEX UNIQUE SCAN | PK_CLIENT | 1 | 3 | 0 (0)| 00:00:01 |
| 17 | TABLE ACCESS FULL | MY_POS | 8738 | 78642 | 1356 (2)| 00:00:17 |
|* 18 | HASH JOIN | | 4956 | 208K| 1583 (2)| 00:00:19 |
| 19 | NESTED LOOPS | | 97 | 3298 | 227 (1)| 00:00:03 |
| 20 | NESTED LOOPS OUTER | | 97 | 3007 | 227 (1)| 00:00:03 |
| 21 | NESTED LOOPS | | 97 | 2328 | 129 (1)| 00:00:02 |
|* 22 | TABLE ACCESS FULL | MY_AGREEMENT | 97 | 1358 | 32 (4)| 00:00:01 |
| 23 | TABLE ACCESS BY INDEX ROWID| MY_ACCOUNT | 1 | 10 | 1 (0)| 00:00:01 |
|* 24 | INDEX UNIQUE SCAN | PK_MY_ACCOUNT | 1 | | 0 (0)| 00:00:01 |
| 25 | TABLE ACCESS BY INDEX ROWID | MY_ACCOUNT | 1 | 7 | 1 (0)| 00:00:01 |
|* 26 | INDEX UNIQUE SCAN | PK_MY_ACCOUNT | 1 | | 0 (0)| 00:00:01 |
|* 27 | INDEX UNIQUE SCAN | PK_CLIENT | 1 | 3 | 0 (0)| 00:00:01 |
| 28 | TABLE ACCESS FULL | MY_POS | 8738 | 78642 | 1356 (2)| 00:00:17 |
|* 29 | HASH JOIN | | 8736 | 366K| 1594 (2)| 00:00:20 |
| 30 | NESTED LOOPS | | 776 | 26384 | 237 (6)| 00:00:03 |
|* 31 | HASH JOIN OUTER | | 776 | 24056 | 236 (5)| 00:00:03 |
|* 32 | HASH JOIN | | 776 | 18624 | 135 (6)| 00:00:02 |
|* 33 | TABLE ACCESS FULL | MY_AGREEMENT | 776 | 10864 | 32 (4)| 00:00:01 |
| 34 | TABLE ACCESS FULL | MY_ACCOUNT || 226K| 101 (4)| 00:00:02 |
| 35 | TABLE ACCESS FULL | MY_ACCOUNT || 158K| 100 (3)| 00:00:02 |
|* 36 | INDEX UNIQUE SCAN | PK_CLIENT | 1 | 3 | 0 (0)| 00:00:01 |
| 37 | TABLE ACCESS FULL | MY_POS | 8738 | 78642 | 1356 (2)| 00:00:17 |
|* 38 | HASH JOIN | | 8733 | 366K| 1596 (2)| 00:00:20 |
| 39 | NESTED LOOPS | | 3075 | 102K| 239 (6)| 00:00:03 |
|* 40 | HASH JOIN OUTER | | 3075 | 95325 | 237 (6)| 00:00:03 |
|* 41 | HASH JOIN | | 3075 | 73800 | 136 (6)| 00:00:02 |
|* 42 | TABLE ACCESS FULL | MY_AGREEMENT | 3075 | 43050 | 33 (7)| 00:00:01 |
| 43 | TABLE ACCESS FULL | MY_ACCOUNT || 226K| 101 (4)| 00:00:02 |
| 44 | TABLE ACCESS FULL | MY_ACCOUNT || 158K| 100 (3)| 00:00:02 |
|* 45 | INDEX UNIQUE SCAN | PK_CLIENT | 1 | 3 | 0 (0)| 00:00:01 |
| 46 | TABLE ACCESS FULL | MY_POS | 8738 | 78642 | 1356 (2)| 00:00:17 |
|* 47 | HASH JOIN | | 9097 | 382K| 1596 (2)| 00:00:20 |
| 48 | NESTED LOOPS | | 3257 | 108K| 240 (7)| 00:00:03 |
|* 49 | HASH JOIN OUTER | | 3257 | 98K| 237 (6)| 00:00:03 |
|* 50 | HASH JOIN | | 3257 | 78168 | 136 (6)| 00:00:02 |
| 51 | TABLE ACCESS FULL | MY_AGREEMENT | 3257 | 45598 | 33 (7)| 00:00:01 |
| 52 | TABLE ACCESS FULL | MY_ACCOUNT || 226K| 101 (4)| 00:00:02 |
| 53 | TABLE ACCESS FULL | MY_ACCOUNT || 158K| 100 (3)| 00:00:02 |
|* 54 | INDEX UNIQUE SCAN | PK_CLIENT | 1 | 3 | 0 (0)| 00:00:01 |
| 55 | TABLE ACCESS FULL | MY_POS | 8738 | 78642 | 1356 (2)| 00:00:17 |
----------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("POS1"."MY_POS_ID"="ITEM_1")
2 - access("MY_SOURCE"="MY_SOURCE_ID")
3 - filter("CAN_DELETE"=0)
7 - access("AGR"."CLIENT_POOL_ACC_ID"="POS"."MY_ACC_ID")
11 - filter("AGR"."CLIENT_POOL_ACC_ID" IS NOT NULL)
13 - access("AGR"."AGR_CLIENT_ACC_ID"="ACC"."MY_ACC_ID")
15 - access("ACC"."FUND_ACC_ID"="FUND_ACC"."MY_ACC_ID"(+))
16 - access("CLI"."CLIENT_ID"=CASE WHEN ("FUND_ACC"."MY_ACC_ID" IS NOT NULL) THEN
"FUND_ACC"."CLIENT_ID" ELSE "ACC"."CLIENT_ID" END)
18 - access("AGR"."AGR_POOL_ACC_ID"="POS"."MY_ACC_ID")
filter(LNNVL("AGR"."CLIENT_POOL_ACC_ID"="POS"."MY_ACC_ID") OR
LNNVL("AGR"."CLIENT_POOL_ACC_ID" IS NOT NULL))
22 - filter("AGR"."AGR_POOL_ACC_ID" IS NOT NULL)
24 - access("AGR"."AGR_CLIENT_ACC_ID"="ACC"."MY_ACC_ID")
26 - access("ACC"."FUND_ACC_ID"="FUND_ACC"."MY_ACC_ID"(+))
27 - access("CLI"."CLIENT_ID"=CASE WHEN ("FUND_ACC"."MY_ACC_ID" IS NOT NULL) THEN
"FUND_ACC"."CLIENT_ID" ELSE "ACC"."CLIENT_ID" END)
29 - access("AGR"."AGR_CLIENT_COLL_ACC_ID"="POS"."MY_ACC_ID")
filter((LNNVL("AGR"."AGR_POOL_ACC_ID"="POS"."MY_ACC_ID") OR
LNNVL("AGR"."AGR_POOL_ACC_ID" IS NOT NULL)) AND
(LNNVL("AGR"."CLIENT_POOL_ACC_ID"="POS"."MY_ACC_ID") OR LNNVL("AGR"."CLIENT_POOL_ACC_ID" IS
NOT NULL)))
31 - access("ACC"."FUND_ACC_ID"="FUND_ACC"."MY_ACC_ID"(+))
32 - access("AGR"."AGR_CLIENT_ACC_ID"="ACC"."MY_ACC_ID")
33 - filter("AGR"."AGR_CLIENT_COLL_ACC_ID" IS NOT NULL)
36 - access("CLI"."CLIENT_ID"=CASE WHEN ("FUND_ACC"."MY_ACC_ID" IS NOT NULL) THEN
"FUND_ACC"."CLIENT_ID" ELSE "ACC"."CLIENT_ID" END)
38 - access("AGR"."AGR_CP_ACC_ID"="POS"."MY_ACC_ID")
filter((LNNVL("AGR"."AGR_CLIENT_COLL_ACC_ID"="POS"."MY_ACC_ID") OR
LNNVL("AGR"."AGR_CLIENT_COLL_ACC_ID" IS NOT NULL)) AND
(LNNVL("AGR"."AGR_POOL_ACC_ID"="POS"."MY_ACC_ID") OR LNNVL("AGR"."AGR_POOL_ACC_ID" IS NOT
NULL)) AND (LNNVL("AGR"."CLIENT_POOL_ACC_ID"="POS"."MY_ACC_ID") OR
LNNVL("AGR"."CLIENT_POOL_ACC_ID" IS NOT NULL)))
40 - access("ACC"."FUND_ACC_ID"="FUND_ACC"."MY_ACC_ID"(+))
41 - access("AGR"."AGR_CLIENT_ACC_ID"="ACC"."MY_ACC_ID")
42 - filter("AGR"."AGR_CP_ACC_ID" IS NOT NULL)
45 - access("CLI"."CLIENT_ID"=CASE WHEN ("FUND_ACC"."MY_ACC_ID" IS NOT NULL) THEN
"FUND_ACC"."CLIENT_ID" ELSE "ACC"."CLIENT_ID" END)
47 - access("AGR"."AGR_CLIENT_ACC_ID"="POS"."MY_ACC_ID")
filter((LNNVL("AGR"."AGR_CP_ACC_ID"="POS"."MY_ACC_ID") OR
LNNVL("AGR"."AGR_CP_ACC_ID" IS NOT NULL)) AND
(LNNVL("AGR"."AGR_CLIENT_COLL_ACC_ID"="POS"."MY_ACC_ID") OR
LNNVL("AGR"."AGR_CLIENT_COLL_ACC_ID" IS NOT NULL)) AND
(LNNVL("AGR"."AGR_POOL_ACC_ID"="POS"."MY_ACC_ID") OR LNNVL("AGR"."AGR_POOL_ACC_ID" IS NOT
NULL)) AND (LNNVL("AGR"."CLIENT_POOL_ACC_ID"="POS"."MY_ACC_ID") OR
LNNVL("AGR"."CLIENT_POOL_ACC_ID" IS NOT NULL)))
49 - access("ACC"."FUND_ACC_ID"="FUND_ACC"."MY_ACC_ID"(+))
50 - access("AGR"."AGR_CLIENT_ACC_ID"="ACC"."MY_ACC_ID")
54 - access("CLI"."CLIENT_ID"=CASE WHEN ("FUND_ACC"."MY_ACC_ID" IS NOT NULL) THEN
"FUND_ACC"."CLIENT_ID" ELSE "ACC"."CLIENT_ID" END)
我的新選擇語句的工作速度比舊的快得多(快80倍! ),但我不知道爲什麼。
我只是將目標表添加到子語句中(新的插入語句跟隨我的註釋),並且幾次運行這兩個語句。他們兩人都給了我相同的結果。然而,原來的平均花費80秒,而新的平均花費1秒。有沒有人可以告訴我爲什麼是這種情況?大部分細節是受歡迎的
最好的方面。
在2015年人們還在使用非ANSI風格的外連接..聳聳肩。 – ErikE