[20220121]開發不應該這樣寫sql2.txt
[20220121]開發不應該這樣寫sql2.txt
--//生產系統遇到的最佳化問題,原始語句很複雜,在測試環境做一個分析並記錄.
1.環境:
SCOTT@book> @ver1
PORT_STRING VERSION BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx 11.2.0.4.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
2.測試例子:
SCOTT@book> variable a number ;
SCOTT@book> exec :a := 7499;
PL/SQL procedure successfully completed.
SCOTT@book> @ sl all
alter session set statistics_level = all;
Session altered.
SCOTT@book> select * from emp where empno = :a or :a =0 ;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
7499 ALLEN SALESMAN 7698 1981-02-20 00:00:00 1600 300 30
SCOTT@book> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID b1b1d5k0f6had, child number 0
-------------------------------------
select * from emp where empno = :a or :a =0
Plan hash value: 3956160932
-----------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | Reads |
-----------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | | 3 (100)| | 1 |00:00:00.01 | 7 | 5 |
|* 1 | TABLE ACCESS FULL| EMP | 1 | 1 | 39 | 3 (0)| 00:00:01 | 1 |00:00:00.01 | 7 | 5 |
-----------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1 / EMP@SEL$1
Peeked Binds (identified by position):
--------------------------------------
1 - (NUMBER): 7499
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(("EMPNO"=:A OR :A=0))
--//開發本意是這樣可以實現帶入0的時候使用全表掃描,而帶入大於0的情況下選擇索引,可是可是oracle的最佳化器沒有這麼智慧,不知道開發的想法.
--//好久不做這類最佳化了,你可以測試單獨使用USE_CONCAT提示無效.
select /*+ USE_CONCAT(@"SEL$1") */ * from emp where (empno = :a or :a =0);
select /*+ USE_CONCAT */ * from emp where (empno = :a or :a =0);
--//提示無效,大家可以看看很久以前的測試,連結:
--//http://blog.itpub.net/267265/viewspace-1788598/ =>[20150901]提示USE_CONCAT.txt
--//必須寫成如下:
--//select /*+ USE_CONCAT(@"SEL$1" OR_PREDICATES(1)) */ * from emp where (empno = :a or :a =0);
--//select /*+ USE_CONCAT(@"SEL$1" 8 OR_PREDICATES(1)) */ * from emp where (empno = :a or :a =0);
SCOTT@book> select /*+ USE_CONCAT(@"SEL$1" 8 OR_PREDICATES(1)) */ * from emp where (empno = :a or :a =0);
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
7499 ALLEN SALESMAN 7698 1981-02-20 00:00:00 1600 300 30
SCOTT@book> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID 64amtw9gz3kry, child number 0
-------------------------------------
select /*+ USE_CONCAT(@"SEL$1" 8 OR_PREDICATES(1)) */ * from emp where
(empno = :a or :a =0)
Plan hash value: 3475259919
----------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | | 4 (100)| | 1 |00:00:00.01 | 2 |
| 1 | CONCATENATION | | 1 | | | | | 1 |00:00:00.01 | 2 |
|* 2 | FILTER | | 1 | | | | | 0 |00:00:00.01 | 0 |
| 3 | TABLE ACCESS FULL | EMP | 0 | 14 | 546 | 3 (0)| 00:00:01 | 0 |00:00:00.01 | 0 |
|* 4 | FILTER | | 1 | | | | | 1 |00:00:00.01 | 2 |
| 5 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 1 | 39 | 1 (0)| 00:00:01 | 1 |00:00:00.01 | 2 |
|* 6 | INDEX UNIQUE SCAN | PK_EMP | 1 | 1 | | 0 (0)| | 1 |00:00:00.01 | 1 |
----------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
3 - SEL$1_1 / EMP@SEL$1
5 - SEL$1_2 / EMP@SEL$1_2
6 - SEL$1_2 / EMP@SEL$1_2
Peeked Binds (identified by position):
--------------------------------------
1 - (NUMBER): 7499
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(:A=0)
4 - filter(LNNVL(:A=0))
6 - access("EMPNO"=:A)
--//少量出現可以使用sql profile之類穩定執行計劃,但是如果多次出現使用sql profile就很麻煩,建議開發不要在應該中使用這樣的編寫sql模式.
--//或者稱為技巧.加入判斷來構件sql 語句.
--//我真心很奇怪,在exadata上要7秒才能完成的語句,開發居然也把它上線,不仔細看看嗎?
> @dashtop sql_id,event sql_id='ay987w0c6r8rv' sysdate-4 sysdate-1
Total
Seconds AAS %This SQL_ID EVENT FIRST_SEEN LAST_SEEN
--------- ------- ------- ------------- ------------------------------------------ ------------------- -------------------
17420 .1 64% ay987w0c6r8rv 2022-01-17 19:54:09 2022-01-18 20:30:46
9520 .0 35% ay987w0c6r8rv cell smart table scan 2022-01-17 19:42:21 2022-01-18 20:29:05
40 .0 0% ay987w0c6r8rv enq: KO - fast object checkpoint 2022-01-18 11:12:51 2022-01-18 19:40:50
40 .0 0% ay987w0c6r8rv gc cr block 2-way 2022-01-18 11:08:48 2022-01-18 15:56:37
20 .0 0% ay987w0c6r8rv reliable message 2022-01-18 11:03:23 2022-01-18 11:28:34
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2853429/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20231207]開發不應該這樣寫sql4.txtSQL
- [20220124]開發不應該這樣寫sql3.txtSQL
- [20220109]開發不應該這樣寫SQL語句.txtSQL
- markdown裡的微積分中dt應該這樣寫
- 一份優秀的資料分析報告應該這樣寫
- Clipped.js | Webpack 應該這樣用JSWeb
- 轉行做Java開發應該怎樣學習?Java
- MySQL備份指令碼,應該這麼寫MySql指令碼
- 企業通關必備,iPaaS應該這樣搭建
- Yann LeCun:未來的AI晶片應該這樣做Yann LeCunAI晶片
- 教育小程式原始碼開發熱度不減,教培機構應該抓住這個機遇原始碼
- 當代前端應該怎麼寫這個hello world?前端
- “掃蕩”、“自動尋路”這樣的簡化遊戲設計該不該存在?遊戲設計
- PHP做api開發離不開簽名驗證,我這樣設計PHPAPI
- Python遠端登陸伺服器應該這樣玩Python伺服器
- 年終了,程式設計師應該這樣談加薪!程式設計師
- 關於 JavaScript 中的特殊函式,你應該這樣看JavaScript函式
- 這樣講 SpringBoot 自動配置原理,你應該能明白了吧Spring Boot
- Laravel 路由這樣寫 "{article}"Laravel路由
- 還在為找資料而發愁嗎?看完這篇應該再也不會了
- 這就是我心目中獨立遊戲應該有的樣子遊戲
- vue3+ts+vite2環境變數應該這樣使用VueVite變數
- 我們究竟應不應該使用框架?框架
- 我不應該用JWT的!JWT
- LeetCode應該這麼刷!LeetCode
- 優思學院|Minitab中的子組大小應該怎樣填寫?
- 這樣delete居然不走索引delete索引
- [20220121]Hash Aggregation.txt
- Android開發應該掌握的Proguard技巧Android
- Android 開發應該掌握的 Proguard 技巧Android
- 跨境電商app應該如何開發?APP
- 親身經驗分享|短影片本地同城專案應該這樣做
- Node.js流,這樣的開啟方式對不對!Node.js
- Python 生成器不該這麼用Python
- 作為遊戲開發商,應該怎樣去提升遊戲的變現能力?遊戲開發
- 資料庫讀寫分離這個坑,你應該踩過吧?資料庫
- 遊戲不應該只有樂趣遊戲
- 怎樣讓C不這麼難