[20130411]timestamp資料型別與運算.txt
[20130411]timestamp資料型別與運算.txt
昨天檢視sql語句,發現程式設計師使用日期型別有問題,使用了timestamp資料型別。
拿scott.emp表作為例子來說明:
create index i_emp_hiredate on emp(hiredate) ;
在hiredate上建立索引。
--可以發現由於使用變數為timestamp型別,導致存在隱式轉換,不可能使用索引。
--但是我覺得奇怪的是如果加入運算,問題消失。
--有點不好理解,透過運算,應該型別不變才對!可以透過這個方式來快速修改程式碼。
--再寫幾個例子:
昨天檢視sql語句,發現程式設計師使用日期型別有問題,使用了timestamp資料型別。
拿scott.emp表作為例子來說明:
create index i_emp_hiredate on emp(hiredate) ;
在hiredate上建立索引。
SQL> @ver
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
SQL> variable x varchar2(40)
SQL> exec :x := '1980-12-17 00:00:00';
PL/SQL procedure successfully completed.
SQL> select * from emp where hiredate = to_timestamp(:x,'yyyy-mm-dd hh24:mi:ss') ;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 1980-12-17 00:00:00 800 20
SQL> @dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------
SQL_ID 5wx35kzbmxmu8, child number 0
-------------------------------------
select * from emp where hiredate = to_timestamp(:x,'yyyy-mm-dd
hh24:mi:ss')
Plan hash value: 3956160932
--------------------------------------------------------
| Id | Operation | Name | E-Rows | Cost (%CPU)|
--------------------------------------------------------
| 0 | SELECT STATEMENT | | | 3 (100)|
|* 1 | TABLE ACCESS FULL| EMP | 1 | 3 (0)|
--------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(INTERNAL_FUNCTION("HIREDATE")=TO_TIMESTAMP(:X,'yyyy-mm-dd
hh24:mi:ss'))
--可以發現由於使用變數為timestamp型別,導致存在隱式轉換,不可能使用索引。
--但是我覺得奇怪的是如果加入運算,問題消失。
SQL> select * from emp where hiredate = to_timestamp(:x,'yyyy-mm-dd hh24:mi:ss')+0 ;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 1980-12-17 00:00:00 800 20
SQL> @dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID fb2pd2pbgx2q9, child number 0
-------------------------------------
select * from emp where hiredate = to_timestamp(:x,'yyyy-mm-dd
hh24:mi:ss')+0
Plan hash value: 3350871025
----------------------------------------------------------------------------
| Id | Operation | Name | E-Rows | Cost (%CPU)|
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 2 (100)|
| 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 2 (0)|
|* 2 | INDEX RANGE SCAN | I_EMP_HIREDATE | 1 | 1 (0)|
----------------------------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
1 - (VARCHAR2(30), CSID=852): '1980-12-17 00:00:00'
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("HIREDATE"=TO_TIMESTAMP(:X,'yyyy-mm-dd hh24:mi:ss')+0)
--有點不好理解,透過運算,應該型別不變才對!可以透過這個方式來快速修改程式碼。
--再寫幾個例子:
SQL> select * from emp where hiredate = to_timestamp(:x,'yyyy-mm-dd hh24:mi:ss')+interval '0' second ;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 1980-12-17 00:00:00 800 20
SQL> @dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID fnk6fn50ybfmb, child number 0
-------------------------------------
select * from emp where hiredate = to_timestamp(:x,'yyyy-mm-dd
hh24:mi:ss')+interval '0' second
Plan hash value: 3956160932
--------------------------------------------------------
| Id | Operation | Name | E-Rows | Cost (%CPU)|
--------------------------------------------------------
| 0 | SELECT STATEMENT | | | 3 (100)|
|* 1 | TABLE ACCESS FULL| EMP | 1 | 3 (0)|
--------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(INTERNAL_FUNCTION("HIREDATE")=TO_TIMESTAMP(:X,'yyyy-mm-dd
hh24:mi:ss')+INTERVAL'+00 00:00:00.000000' DAY(2) TO SECOND(6))
--這樣寫不行。
SQL> select * from emp where hiredate = to_date(:x,'yyyy-mm-dd hh24:mi:ss')+interval '0' second ;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 1980-12-17 00:00:00 800 20
SQL> @dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID 6xvckc7tbhudj, child number 0
-------------------------------------
select * from emp where hiredate = to_date(:x,'yyyy-mm-dd
hh24:mi:ss')+interval '0' second
Plan hash value: 3350871025
----------------------------------------------------------------------------
| Id | Operation | Name | E-Rows | Cost (%CPU)|
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 2 (100)|
| 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 2 (0)|
|* 2 | INDEX RANGE SCAN | I_EMP_HIREDATE | 1 | 1 (0)|
----------------------------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
1 - (VARCHAR2(30), CSID=852): '1980-12-17 00:00:00'
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("HIREDATE"=TO_DATE(:X,'yyyy-mm-dd
hh24:mi:ss')+INTERVAL'+00 00:00:00.000000' DAY(2) TO SECOND(6))
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-758233/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- timestamp型別的加減運算型別
- 如何在運算過程中保留timestamp型別資料的毫秒精度?型別
- oracle中date資料型別與timestamp資料型別的轉換Oracle資料型別
- [大資料量]java移位運算與位運算與資料型別的儲存大資料Java資料型別
- mysql 資料型別TIMESTAMPMySQL 資料型別
- Sqlserver:timestamp資料型別SQLServer資料型別
- ORACLE TIMESTAMP資料型別Oracle資料型別
- timestamp資料型別求差資料型別
- 關於timestamp資料型別資料型別
- 二、python的邏輯運算與資料型別Python資料型別
- JAVA_資料型別介紹與基本資料型別之間的運算規則Java資料型別
- MySQL資料庫中的timestamp型別與時區MySql資料庫型別
- JavaScript資料型別與運算子JavaScript資料型別
- Oracle中的TIMESTAMP資料型別Oracle資料型別
- ORACLE DATE型別和TIMESTAMP型別DUMP換算Oracle型別
- C語言資料型別和算數運算C語言資料型別
- oracle將表中date資料型別修改為timestamp資料型別Oracle資料型別
- 列舉型別與位運算型別
- [20191219]oracle timestamp資料型別的儲存.txtOracle資料型別
- javaScript資料型別與typeof運算子JavaScript資料型別
- python資料型別和四則運算Python資料型別
- C#插入Oracle中Timestamp型別資料C#Oracle型別
- [20241009]oracle timestamp with time zone資料型別的儲存.txtOracle資料型別
- oracle資料型別date和timestamp的轉化Oracle資料型別
- 不同型別資料運算型別
- 資料型別和運算子資料型別
- Toad 與 timestamp 型別的問題?型別
- 基本資料型別與字串型別資料型別字串
- 輸入TIMESTAMP型別型別
- Timestamp型別淺析型別
- Sybase的timestamp型別型別
- 【java資料型別和運算子】Java資料型別
- ORACLE DATE和TIMESTAMP資料型別的比較(一) (轉)Oracle資料型別
- ORACLE DATE和TIMESTAMP資料型別的比較(二) (轉)Oracle資料型別
- 混合運算中資料型別的轉換 (轉)資料型別
- 將timestamp型別轉換為date型別型別
- Java中的基本資料型別與引用資料型別Java資料型別
- (轉)PLS_INTEGER型別與timestamp型別、date、及時間函式型別函式