高效的SQL(清晰的邏輯重構業務SQL)
高效的SQL(清晰的邏輯重構業務SQL)
業務SQL如下
select to_char(t.entertime, 'yyyymmdd') AS time,
t.userid,
--振鈴通話時間
sum(ROUND(TO_NUMBER(t.turnontime - t.ringtime) * 24 * 60 * 60)) AS t_ring,
--進線量
count(case
when (((select ceil((t1.custhanguptime - t1.ringtime) * 24 * 60 * 60) sh
FROM doudou t1
where t1.custhanguptime is not null and t1.callid=t.callid
and t1.ringtime is not null) > 5 or
(t.custhanguptime is null))) then
1
else
null
end) as n_enter,
--呼入通話時長
sum(ROUND(TO_NUMBER(t.hanguptime - t.turnontime) * 24 * 60 * 60)) AS t_inbound
from doudou t
where t.ringtime is not null
Group by to_char(t.entertime, 'yyyymmdd'), t.userid;
索引如下
alter table DOUDOU
add constraint DOUDOU_PK_CALLID primary key (CALLID)
using index
tablespace CMSDATA
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
);
Elapsed: 00:00:13.96
Execution Plan
----------------------------------------------------------
Plan hash value: 2637126917
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 691K| 45M| 5971 (3)| 00:01:12 |
|* 1 | TABLE ACCESS BY INDEX ROWID| DOUDOU | 1 | 30 | 3 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | DOUDOU_PK_CALLID | 1 | | 2 (0)| 00:00:01 |
| 3 | HASH GROUP BY | | 691K| 45M| 5971 (3)| 00:01:12 |
|* 4 | TABLE ACCESS FULL | DOUDOU | 691K| 45M| 5921 (2)| 00:01:12 |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("T1"."CUSTHANGUPTIME" IS NOT NULL AND "T1"."RINGTIME" IS NOT NULL)
2 - access("T1"."CALLID"=:B1)
4 - filter("T"."RINGTIME" IS NOT NULL)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
78 recursive calls
0 db block gets
1191076 consistent gets <==邏輯讀過多
4080 physical reads
0 redo size
542664 bytes sent via SQL*Net to client
10904 bytes received via SQL*Net from client
946 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
14169 rows processed
優化思想
1.解決TAF問題
2.如果解決不了TAF,瘦身DOUDOU這張表的有效資料,這樣可以減少consistent gets
1.解決TAF問題
1252852 DOUDOU
563939 ringtime is not null
1901 ringtime is not null AND custhanguptime is not null
create index idx_zuhe on doudou (custhanguptime,ringtime,CALLID);
exec dbms_stats.gather_table_stats(user,'DOUDOU',cascade=>true);
##經過複合索引,效果並不明顯。所以選擇瘦身DOUDOU表。
##使用分割槽表進行瘦身
2.如果解決不了TAF,瘦身DOUDOU這張表的有效資料,這樣可以減少consistent gets
select to_char(t.entertime, 'yyyymmdd') AS time,
t.userid,
--振鈴通話時間
sum(ROUND(TO_NUMBER(t.turnontime - t.ringtime) * 24 * 60 * 60)) AS t_ring,
--進線量
count(case
when (((select ceil((t1.custhanguptime - t1.ringtime) * 24 * 60 * 60) sh
FROM doudou t1
where t1.custhanguptime is not null and t1.callid=t.callid
and t1.ringtime is not null) > 5 or
(t.custhanguptime is null))) then
1
else
null
end) as n_enter,
--呼入通話時長
sum(ROUND(TO_NUMBER(t.hanguptime - t.turnontime) * 24 * 60 * 60)) AS t_inbound
from doudou t
where
to_char(t.entertime, 'yyyymmdd') like '201607%' and --重構SQL,瘦身DOUDOU表的有效資料。
t.ringtime is not null
Group by to_char(t.entertime, 'yyyymmdd'), t.userid ;
194 rows selected.
Elapsed: 00:00:01.76
Execution Plan
----------------------------------------------------------
Plan hash value: 2637126917
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 28374 | 1246K| | 6240 (2)| 00:01:15 |
|* 1 | TABLE ACCESS BY INDEX ROWID| DOUDOU | 1 | 24 | | 3 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | DOUDOU_PK_CALLID | 1 | | | 2 (0)| 00:00:01 |
| 3 | HASH GROUP BY | | 28374 | 1246K| 1800K| 6240 (2)| 00:01:15 |
|* 4 | TABLE ACCESS FULL | DOUDOU | 28374 | 1246K| | 5914 (2)| 00:01:11 |
--------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("T1"."CUSTHANGUPTIME" IS NOT NULL AND "T1"."RINGTIME" IS NOT NULL)
2 - access("T1"."CALLID"=:B1)
4 - filter("T"."RINGTIME" IS NOT NULL AND TO_CHAR(INTERNAL_FUNCTION("T"."ENTERTIME"),'yyyymmd
d') LIKE '201607%')
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
44513 consistent gets <==業務SQL重構後,基本滿足需求
0 physical reads
0 redo size
8099 bytes sent via SQL*Net to client
652 bytes received via SQL*Net from client
14 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
194 rows processed
##根據業務邏輯,瘦身DOUDOU之後邏輯讀從1191076優化至44513。優化了26倍。
##此業務SQL經跟業務人員溝通,當月的資料就可以滿足業務需求。所以重構了業務SQL減少邏輯讀。
總結:
優化往往是優化寫SQL的一種思想,這種思想的核心就是用最小的資料來完成需求。無關的資料都是"砍!砍!砍!"掉
########################################################################################
版權所有,文章允許轉載,但必須以連結方式註明源地址,否則追究法律責任!【QQ交流群:53993419】
QQ:14040928 E-mail:dbadoudou@163.com
本文連結: http://blog.itpub.net/26442936/viewspace-2121889/
########################################################################################
業務SQL如下
select to_char(t.entertime, 'yyyymmdd') AS time,
t.userid,
--振鈴通話時間
sum(ROUND(TO_NUMBER(t.turnontime - t.ringtime) * 24 * 60 * 60)) AS t_ring,
--進線量
count(case
when (((select ceil((t1.custhanguptime - t1.ringtime) * 24 * 60 * 60) sh
FROM doudou t1
where t1.custhanguptime is not null and t1.callid=t.callid
and t1.ringtime is not null) > 5 or
(t.custhanguptime is null))) then
1
else
null
end) as n_enter,
--呼入通話時長
sum(ROUND(TO_NUMBER(t.hanguptime - t.turnontime) * 24 * 60 * 60)) AS t_inbound
from doudou t
where t.ringtime is not null
Group by to_char(t.entertime, 'yyyymmdd'), t.userid;
索引如下
alter table DOUDOU
add constraint DOUDOU_PK_CALLID primary key (CALLID)
using index
tablespace CMSDATA
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
);
Elapsed: 00:00:13.96
Execution Plan
----------------------------------------------------------
Plan hash value: 2637126917
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 691K| 45M| 5971 (3)| 00:01:12 |
|* 1 | TABLE ACCESS BY INDEX ROWID| DOUDOU | 1 | 30 | 3 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | DOUDOU_PK_CALLID | 1 | | 2 (0)| 00:00:01 |
| 3 | HASH GROUP BY | | 691K| 45M| 5971 (3)| 00:01:12 |
|* 4 | TABLE ACCESS FULL | DOUDOU | 691K| 45M| 5921 (2)| 00:01:12 |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("T1"."CUSTHANGUPTIME" IS NOT NULL AND "T1"."RINGTIME" IS NOT NULL)
2 - access("T1"."CALLID"=:B1)
4 - filter("T"."RINGTIME" IS NOT NULL)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
78 recursive calls
0 db block gets
1191076 consistent gets <==邏輯讀過多
4080 physical reads
0 redo size
542664 bytes sent via SQL*Net to client
10904 bytes received via SQL*Net from client
946 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
14169 rows processed
優化思想
1.解決TAF問題
2.如果解決不了TAF,瘦身DOUDOU這張表的有效資料,這樣可以減少consistent gets
1.解決TAF問題
1252852 DOUDOU
563939 ringtime is not null
1901 ringtime is not null AND custhanguptime is not null
create index idx_zuhe on doudou (custhanguptime,ringtime,CALLID);
exec dbms_stats.gather_table_stats(user,'DOUDOU',cascade=>true);
##經過複合索引,效果並不明顯。所以選擇瘦身DOUDOU表。
##使用分割槽表進行瘦身
2.如果解決不了TAF,瘦身DOUDOU這張表的有效資料,這樣可以減少consistent gets
select to_char(t.entertime, 'yyyymmdd') AS time,
t.userid,
--振鈴通話時間
sum(ROUND(TO_NUMBER(t.turnontime - t.ringtime) * 24 * 60 * 60)) AS t_ring,
--進線量
count(case
when (((select ceil((t1.custhanguptime - t1.ringtime) * 24 * 60 * 60) sh
FROM doudou t1
where t1.custhanguptime is not null and t1.callid=t.callid
and t1.ringtime is not null) > 5 or
(t.custhanguptime is null))) then
1
else
null
end) as n_enter,
--呼入通話時長
sum(ROUND(TO_NUMBER(t.hanguptime - t.turnontime) * 24 * 60 * 60)) AS t_inbound
from doudou t
where
to_char(t.entertime, 'yyyymmdd') like '201607%' and --重構SQL,瘦身DOUDOU表的有效資料。
t.ringtime is not null
Group by to_char(t.entertime, 'yyyymmdd'), t.userid ;
194 rows selected.
Elapsed: 00:00:01.76
Execution Plan
----------------------------------------------------------
Plan hash value: 2637126917
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 28374 | 1246K| | 6240 (2)| 00:01:15 |
|* 1 | TABLE ACCESS BY INDEX ROWID| DOUDOU | 1 | 24 | | 3 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | DOUDOU_PK_CALLID | 1 | | | 2 (0)| 00:00:01 |
| 3 | HASH GROUP BY | | 28374 | 1246K| 1800K| 6240 (2)| 00:01:15 |
|* 4 | TABLE ACCESS FULL | DOUDOU | 28374 | 1246K| | 5914 (2)| 00:01:11 |
--------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("T1"."CUSTHANGUPTIME" IS NOT NULL AND "T1"."RINGTIME" IS NOT NULL)
2 - access("T1"."CALLID"=:B1)
4 - filter("T"."RINGTIME" IS NOT NULL AND TO_CHAR(INTERNAL_FUNCTION("T"."ENTERTIME"),'yyyymmd
d') LIKE '201607%')
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
44513 consistent gets <==業務SQL重構後,基本滿足需求
0 physical reads
0 redo size
8099 bytes sent via SQL*Net to client
652 bytes received via SQL*Net from client
14 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
194 rows processed
##根據業務邏輯,瘦身DOUDOU之後邏輯讀從1191076優化至44513。優化了26倍。
##此業務SQL經跟業務人員溝通,當月的資料就可以滿足業務需求。所以重構了業務SQL減少邏輯讀。
總結:
優化往往是優化寫SQL的一種思想,這種思想的核心就是用最小的資料來完成需求。無關的資料都是"砍!砍!砍!"掉
########################################################################################
版權所有,文章允許轉載,但必須以連結方式註明源地址,否則追究法律責任!【QQ交流群:53993419】
QQ:14040928 E-mail:dbadoudou@163.com
本文連結: http://blog.itpub.net/26442936/viewspace-2121889/
########################################################################################
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26442936/viewspace-2121889/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL Server中TempDB管理(version store的邏輯結構)SQLServer
- 儘量用簡單的SQL替代PL/SQL邏輯SQL
- 編寫業務邏輯程式碼,清晰可維護是很重要的
- 【SQL 優化】異常的邏輯讀SQL優化
- sql語句中較為重要的查詢邏輯SQL
- sql生成可讀性邏輯圖SQL
- sql優化之邏輯優化SQL優化
- 銀行支付的業務邏輯和各機構關係
- [TEAP早期試讀]在資料庫中使用PL/SQL實現業務邏輯的優勢資料庫SQL
- 如何將SQL寫成複雜邏輯 和構造資料SQL
- MySQL之SQL邏輯查詢順序MySql
- 業務邏輯學習!
- oracle的邏輯結構Oracle
- SPA PLM 核心業務邏輯
- 業務邏輯漏洞和cs
- 程式碼重構之 —— 一堆if、esle 邏輯的處理
- [zt] Oracle的邏輯結構Oracle
- 淺談SQL Server中的事務日誌(一)----事務日誌的物理和邏輯構架SQLServer
- SQL Select語句邏輯執行順序SQL
- 邏輯有點難理解的Sql執行結果,以及用處SQL
- SQL Server效能的改進得益於邏輯資料庫設計SQLServer資料庫
- 實現拼團業務邏輯
- 強業務邏輯抽象API介面抽象API
- 用java實現業務邏輯Java
- bp靶場業務邏輯漏洞
- 業務邏輯開發套路的三板斧
- 不懂業務的SQL優化方法SQL優化
- SQL邏輯查詢處理順序特別提醒SQL
- eKuiper Newsletter 2022-07|v1.6.0:Flow 編排 + 更好用的 SQL,輕鬆表達業務邏輯UISQL
- 單條SQL語句實現複雜邏輯的幾個例子(1)SQL
- 單條SQL語句實現複雜邏輯的幾個例子(2)SQL
- 單條SQL語句實現複雜邏輯的幾個例子(3)SQL
- 單條SQL語句實現複雜邏輯的幾個例子(4)SQL
- 單條SQL語句實現複雜邏輯的幾個例子(5)SQL
- SQL Server資料庫出現邏輯錯誤的資料恢復SQLServer資料庫資料恢復
- 【總結】去重的SQLSQL
- 經典SQL面試題4:高效的刪除重複記錄方法SQL面試題
- PostgreSQL:邏輯結構SQL