記一次sql優化
今天開發有個應用sql跑了幾十分鐘也沒出現結果,他的方法:
1:A和B表都有20多萬行資料,開發用B表每次取出1000行做去重操作然後再和A表聯合將需要的結果放到一個臨時表中
2:兩個20多萬行的表資料直接聯合取資料放到臨時表
以上2種方法都不盡人意,以下是優化過程
[oracle@localhost ~]$ sqlplus /nolog
SQL*Plus: Release 10.2.0.4.0 - Production on Thu Jul 26 14:30:07 2012
Copyright (c) 1982, 2007, Oracle. All Rights Reserved.
SQL> conn test/test
Connected.
SQL> set timing on
SQL> set autot exp stat
Usage: SET AUTOT[RACE] {OFF | ON | TRACE[ONLY]} [EXP[LAIN]] [STAT[ISTICS]]
SQL> set autot trace exp stat
SQL>
SQL> SELECT
2 b.id,b.x, b.y,b.z,a.m,a.l,a.h,a.i,a.xx,b.yy
3 FROM a, b
4 WHERE a.col1=b.col2
5 AND b.col2 is not null
6 AND a.col1 is not null;
Connected.
SQL> set timing on
SQL> set autot exp stat
Usage: SET AUTOT[RACE] {OFF | ON | TRACE[ONLY]} [EXP[LAIN]] [STAT[ISTICS]]
SQL> set autot trace exp stat
SQL>
SQL> SELECT
2 b.id,b.x, b.y,b.z,a.m,a.l,a.h,a.i,a.xx,b.yy
3 FROM a, b
4 WHERE a.col1=b.col2
5 AND b.col2 is not null
6 AND a.col1 is not null;
12903 rows selected.
Elapsed: 00:00:19.26
Execution Plan
----------------------------------------------------------
Plan hash value: 4038516337
----------------------------------------------------------
Plan hash value: 4038516337
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 645K| 86M| | 67511 (1)| 00:13:31 |
|* 1 | HASH JOIN | | 645K| 86M|31M| 67511 (1)| 00:13:31 |
|* 2 | TABLE ACCESS FULL| | 442K| 26M| | 45086 (1)| 00:09:02 |
|* 3 | TABLE ACCESS FULL| | 2226K| 163M| | 11463 (1)| 00:02:18 |
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 645K| 86M| | 67511 (1)| 00:13:31 |
|* 1 | HASH JOIN | | 645K| 86M|31M| 67511 (1)| 00:13:31 |
|* 2 | TABLE ACCESS FULL| | 442K| 26M| | 45086 (1)| 00:09:02 |
|* 3 | TABLE ACCESS FULL| | 2226K| 163M| | 11463 (1)| 00:02:18 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
---------------------------------------------------
1 - access("A"."COL1"="B"."COL2")
2 - filter("A"."COL1" IS NOT NULL)
3 - filter("B"."COL2" IS NOT NULL)
2 - filter("A"."COL1" IS NOT NULL)
3 - filter("B"."COL2" IS NOT NULL)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
256930 consistent gets
138271 physical reads
0 redo size
1468518 bytes sent via SQL*Net to client
9952 bytes received via SQL*Net from client
862 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
12903 rows processed
SQL>
create index idx_col1 on (col1) tablespace xx_index;
create index idx_col2 on (col2) tablespace xx_index;
drop table tmpyj;
CREATE TABLE tmpyj
AS
SELECT /*+ index(a,idx_col1) index(b,idx_col2) */
b.id,b.x, b.y,b.z,a.m,a.l,a.h,a.i,a.xx,b.yy
FROM a, b
WHERE a.col1=b.col2
AND b.col2 is not null
AND a.col1 is not null;
SELECT
id,x,y,z,m,l,h,i,xx,yy
FROM (
SELECT
a.*,ROW_NUMBER() OVER (PARTITION BY col2 ORDER BY yy DESC) RN
FROM tmpyj a
)
WHERE rn=1;
CREATE TABLE tmpyj
AS
SELECT /*+ index(a,idx_col1) index(b,idx_col2) */
b.id,b.x, b.y,b.z,a.m,a.l,a.h,a.i,a.xx,b.yy
FROM a, b
WHERE a.col1=b.col2
AND b.col2 is not null
AND a.col1 is not null;
SELECT
id,x,y,z,m,l,h,i,xx,yy
FROM (
SELECT
a.*,ROW_NUMBER() OVER (PARTITION BY col2 ORDER BY yy DESC) RN
FROM tmpyj a
)
WHERE rn=1;
SQL> SELECT /*+ index(a,idx_col1) index(b,idx_col2) */
2 b.id,b.x, b.y,b.z,a.m,a.l,a.h,a.i,a.xx,b.yy
3 FROM a, b
4 WHERE a.col1=b.col2
5 AND b.col2 is not null
6 AND a.col1 is not null;
2 b.id,b.x, b.y,b.z,a.m,a.l,a.h,a.i,a.xx,b.yy
3 FROM a, b
4 WHERE a.col1=b.col2
5 AND b.col2 is not null
6 AND a.col1 is not null;
12903 rows selected.
Elapsed: 00:00:02.95
Execution Plan
----------------------------------------------------------
Plan hash value: 2104990369
----------------------------------------------------------
Plan hash value: 2104990369
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 645K| 86M| 1686K (1)| 05:37:14 |
| 1 | TABLE ACCESS BY INDEX ROWID | | 1 | 77 | 4 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | 645K| 86M| 1686K (1)| 05:37:14 |
| 3 | TABLE ACCESS BY INDEX ROWID| | 442K| 26M| 355K (1)| 01:11:07 |
|* 4 | INDEX FULL SCAN | idx_col1 | 437K| | 1316 (1)| 00:00:16 |
|* 5 | INDEX RANGE SCAN | idx_col2 | 2 | | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 645K| 86M| 1686K (1)| 05:37:14 |
| 1 | TABLE ACCESS BY INDEX ROWID | | 1 | 77 | 4 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | 645K| 86M| 1686K (1)| 05:37:14 |
| 3 | TABLE ACCESS BY INDEX ROWID| | 442K| 26M| 355K (1)| 01:11:07 |
|* 4 | INDEX FULL SCAN | idx_col1 | 437K| | 1316 (1)| 00:00:16 |
|* 5 | INDEX RANGE SCAN | idx_col2 | 2 | | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
---------------------------------------------------
4 - filter("A"."COL1" IS NOT NULL)
5 - access("A"."COL1"="B"."COL2")
filter("B"."COL2" IS NOT NULL)
5 - access("A"."COL1"="B"."COL2")
filter("B"."COL2" IS NOT NULL)
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
1245150 consistent gets
0 physical reads
0 redo size
1092468 bytes sent via SQL*Net to client
9952 bytes received via SQL*Net from client
862 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
12903 rows processed
SQL>
優化思路:
優化前:sql返回結果時間是19.26秒,邏輯讀和物理讀都達到了10萬多,全表掃描,兩表之間是雜湊連線
優化後:新增了索引及sql hint使得執行計劃走索引的路線,兩表之間是迴圈巢狀連線,雖然邏輯讀達到了百萬,但是消除了從物理磁碟讀取資料,且返回結果時間得到了明顯的提升,在2.95秒內就可以返回結果;去重操作沒有放在兩個大表聯合時候做,是因為在大表聯合時候去去重使得sql變的更加複雜,寫出高效的sql機率減小,故放在有2000行的小表裡去重(這裡用的是oracle 分析函式,按col2欄位分割槽,然後按照更新時間倒序排序,然後再取出第一條資料就是我們所要的結果)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16400082/viewspace-736972/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 記一次SQL Server刪除SQL調優SQLServer
- 記錄一次SQL函式和優化的問題SQL函式優化
- 記一次SQL調優過程SQL
- 記一次分頁優化優化
- ? 記一次前端效能優化前端優化
- 記錄一次打包優化優化
- 慢SQL優化實戰筆記SQL優化筆記
- 記一次Elasticsearch優化總結Elasticsearch優化
- 記一次 Webpack 專案優化Web優化
- SQL Server一次SQL調優案例SQLServer
- 一次非常有趣的 SQL 優化經歷SQL優化
- 一次非常有趣的sql優化經歷SQL優化
- 記一次 spinor flash 讀速度優化優化
- 記一次公司產品「負」優化優化
- 記一次Node專案的優化優化
- 漫漫優化路,總會錯幾步(記一次介面優化)優化
- 記一次提升18倍的效能優化優化
- 記一次Prometheus代理效能優化問題Prometheus優化
- 記一次 VUE 專案優化實踐Vue優化
- 資料庫優化 - SQL優化資料庫優化SQL
- sql優化之邏輯優化SQL優化
- SQL SERVER優化SQLServer優化
- SQL優化指南SQL優化
- 記一次mysql 4.5GB大表優化MySql優化
- 記一次服務端系統效能優化服務端優化
- 記一次真實的webpack優化經歷Web優化
- 記一次bem命名規範使用優化方案優化
- Oracle效能優化-SQL優化(案例一)Oracle優化SQL
- Oracle效能優化-SQL優化(案例二)Oracle優化SQL
- Oracle效能優化-SQL優化(案例三)Oracle優化SQL
- Oracle效能優化-SQL優化(案例四)Oracle優化SQL
- sql優化專題SQL優化
- SQL效能優化技巧SQL優化
- SQL語句優化SQL優化
- 慢Sql優化思路SQL優化
- MySQL-SQL優化MySql優化
- SQL優化參考SQL優化
- Oracle SQL優化之sql tuning advisorOracleSQL優化
- SQL優化案例-使用with as優化Subquery Unnesting(七)SQL優化