[20220815]奇怪的隱式轉換問題(11g測試補充).txt
[20220815]奇怪的隱式轉換問題(11g測試補充).txt
--//生產系統遇到一個奇怪的隱式轉換問題,問題在於沒有發生隱式轉換,前面已經做了一些分析增加11g下的測試情況.
--//測試的結果說明我有點想當然了,實際上從12.2版本開始,oracle就支援這樣的情況,當使用繫結變數時,帶入的繫結變數參
--//數是timestamp型別時,不再存在隱式轉換。即使秒後面的值非0!!
--//我看了我以前寫的[20191219]oracle timestamp資料型別的儲存.txt,如果秒後面的值是0,儲存佔用7個位元組。
--//在11g下做一些補充測試:
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.建立指令碼:
create table empx as select * from emp;
create index i_empx_hiredate on empx(hiredate);
$ cat m9.txt
DECLARE
v_empno number;
v_hiredate1 timestamp(9);
v_hiredate2 timestamp(9);
v_hiredate3 timestamp(9);
v_hiredate4 timestamp(9);
v_hiredate date;
begin
v_hiredate1 := to_timestamp('1980-12-17 00:00:00.000000000','yyyy-mm-dd hh24:mi:ss.ff9') ;
v_hiredate2 := to_timestamp('1980-12-17 10:10:10.000000000','yyyy-mm-dd hh24:mi:ss.ff9') ;
v_hiredate3 := to_timestamp('1980-12-17 00:00:00.000000001','yyyy-mm-dd hh24:mi:ss.ff9') ;
v_hiredate4 := to_timestamp('1980-12-17 00:00:00.000001001','yyyy-mm-dd hh24:mi:ss.ff9') ;
select /*+ test1 */ count(*) into v_empno from empx where hiredate = v_hiredate1;
dbms_output.put_line( 'test 1:'||to_char(v_empno) );
select /*+ test2 */ count(*) into v_empno from empx where hiredate = v_hiredate2;
dbms_output.put_line( 'test 2:'||to_char(v_empno) );
select /*+ test3 */ count(*) into v_empno from empx where hiredate = v_hiredate3;
dbms_output.put_line( 'test 3:'||to_char(v_empno) );
select /*+ test4 */ count(*) into v_empno from empx where hiredate = v_hiredate4;
dbms_output.put_line( 'test 4:'||to_char(v_empno) );
end;
/
3.測試:
--//執行多次,避免對應子游標清除。
SCOTT@book> @ m9.txt
test 1:1
test 2:0
test 3:0
test 4:0
PL/SQL procedure successfully completed.
@ m9.txt
@ m9.txt
@ m9.txt
@ m9.txt
SCOTT@book> select executions,sql_id,sql_text c80 from v$sql where lower(sql_text) like 'select%test%' and sql_text not like '%sql_text%' order by 3;
EXECUTIONS SQL_ID C80
---------- ------------- --------------------------------------------------------------------------------
7 3pdjz4fgwwfj2 SELECT /*+ test1 */ COUNT(*) FROM EMPX WHERE HIREDATE = :B1
7 0juh2dbyx948s SELECT /*+ test2 */ COUNT(*) FROM EMPX WHERE HIREDATE = :B1
7 f04fd6q8z7n9w SELECT /*+ test3 */ COUNT(*) FROM EMPX WHERE HIREDATE = :B1
7 f3gx0d2rfn9sb SELECT /*+ test4 */ COUNT(*) FROM EMPX WHERE HIREDATE = :B1
$ echo 3pdjz4fgwwfj2 0juh2dbyx948s f04fd6q8z7n9w f3gx0d2rfn9sb | tr ' ' '\n' | xargs -IQ sqlplus scott/book @ dpc Q '' '' | grep I_EMPX_HIREDATE
--//沒有返回,說明沒有使用索引I_EMPX_HIREDATE,這4種情況。
$ echo 3pdjz4fgwwfj2 0juh2dbyx948s f04fd6q8z7n9w f3gx0d2rfn9sb | tr ' ' '\n' | xargs -IQ sqlplus scott/book @ dpc Q '' '' | grep EMPX
SELECT /*+ test1 */ COUNT(*) FROM EMPX WHERE HIREDATE = :B1
|* 2 | TABLE ACCESS FULL| EMPX | 1 | 9 | 3 (0)| 00:00:01 |
2 - SEL$1 / EMPX@SEL$1
SELECT /*+ test2 */ COUNT(*) FROM EMPX WHERE HIREDATE = :B1
|* 2 | TABLE ACCESS FULL| EMPX | 1 | 9 | 3 (0)| 00:00:01 |
2 - SEL$1 / EMPX@SEL$1
SELECT /*+ test3 */ COUNT(*) FROM EMPX WHERE HIREDATE = :B1
|* 2 | TABLE ACCESS FULL| EMPX | 1 | 9 | 3 (0)| 00:00:01 |
2 - SEL$1 / EMPX@SEL$1
SELECT /*+ test4 */ COUNT(*) FROM EMPX WHERE HIREDATE = :B1
|* 2 | TABLE ACCESS FULL| EMPX | 1 | 9 | 3 (0)| 00:00:01 |
2 - SEL$1 / EMPX@SEL$1
--//執行選擇全表掃描,可以確定11g下確實發生了隱式轉換。
--//做到這裡我突然想起上線前(估計該專案上線快2年了),對方提出要求一定要在19c下執行,我當時覺得很奇怪,這個專案我不負責。現
--//在想想突然開竅了,他們應用帶入引數日期型別可能大量都是使用timestamp型別,在以前的版本一定會出現隱式轉換問題,導致出
--//現大量效能問題。而使用19c(實際上我的測試12.2以上版本都可以)巧妙的掩蓋這個設計缺陷,可以使用date欄位型別的索引。
--//順便再看看生產系統的情況:
SYS@192.168.100.235:1521/orcl> @ pr
==============================
PORT_STRING : x86_64/Linux 2.4.xx
VERSION : 19.0.0.0.0
BANNER : Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
BANNER_FULL : Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
BANNER_LEGACY : Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
CON_ID : 0
PL/SQL procedure successfully completed.
SYS@192.168.100.235:1521/orcl> SELECT count(*),datatype_string FROM v$sql_bind_capture WHERE datatype_string in ('TIMESTAMP','DATE') group by datatype_string;
COUNT(*) DATATYPE_STRING
---------- ------------------------------
6628 DATE
792 TIMESTAMP
--//哈哈,從記數輸出上可以驗證我的判斷,許多sql語句存在混用的date,timestamp的情況,看來國內的應用IT專案都是豆腐渣工程,
--//也許還給加上一個字首,那就是豆腐渣中的豆腐渣工程。
--//不去探究問題的本質,無語.............
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2910734/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20220811]奇怪的隱式轉換問題(12c補充測試).txt
- [20220811]奇怪的隱式轉換問題.txt
- mysql隱式轉換問題MySql
- scala隱式轉換優先順序問題
- [20140116]檢視?隱式轉換?sql優化問題.txtSQL優化
- [20120601]ITL的問題補充.txt
- itoa函式的奇怪問題函式
- 【原創】由隱式轉換引起的資料庫效能問題資料庫
- js顯式轉換和隱式轉換JS
- javascript 隱式轉換JavaScript
- sql隱式轉換SQL
- Oracle 隱式轉換Oracle
- java隱式轉換Java
- [20220603]測試quiz night(補充).txtUI
- [20211013]測試遠端監聽補充.txt
- [20191106]隱式轉換.txt
- Scala - 隱式轉換和隱式引數
- Scala隱式轉換與隱式引數
- SQL Server資料庫中的資料型別隱式轉換問題SQLServer資料庫資料型別
- 【隱式轉換】注意隱式轉換將導致索引無法使用索引
- Scala Essentials: 隱式轉換
- [] == ![],走進==隱式轉換的世界
- Java資料型別的顯式轉換和隱式轉換Java資料型別
- app 測試環境切換問題APP
- [20190211]簡單測試埠是否開啟(補充).txt
- scala中隱式轉換之隱式轉換呼叫類中本不存在的方法
- [20120201][補充]函式索引與取max值的問題1.txt函式索引
- JavaScript隱式型別轉換JavaScript型別
- MySQL 隱式型別轉換MySql型別
- 【C++】禁止隱式轉換C++
- [20181128]toad連線資料庫的問題(補充).txt資料庫
- Spark中的三種隱式轉換Spark
- 你所忽略的js隱式轉換JS
- MySQL和Oracle中的隱式轉換MySqlOracle
- C++隱式型別的轉換C++型別
- 資料型別的隱式轉換資料型別
- 有趣的JavaScript隱式型別轉換JavaScript型別
- oracle 11g sql plan baseline(5)baseline的問題和補充OracleSQL