带有本地时区CBO格式的Oracle时间戳

时间:2018-05-16 12:42:52

标签: oracle timezone timestamp business-objects cbo

我最近将一些“日期”列转换为“带有本地时区的时间戳(6)”,以便使用oracle本地化功能,而无需修改现有的企业应用程序。

一切都按预期工作:客户端sessiontimezone会对数据的“小时数”产生影响。

我的问题是ORACLE基于成本的优化器看起来不理解我们使用的日期格式,并计算错误的基数。你能帮助我们吗?

重现问题:

ALTER SESSION  SET TIME_ZONE = dbtimezone ;

create table TEST_CBO_TSWLT as (
select 
level as pk,
to_date('01/01/2000','DD/MM/YYYY') + (level/24) as col_date,
to_date('01/01/2000','DD/MM/YYYY') + (level/24) as col_ts_wlt
from dual
connect by level < ((365.25)*24)*10
);

create index TEST_CBO_TSWLT_INDX_DATE on TEST_CBO_TSWLT (col_date);
create index TEST_CBO_TSWLT_INDX_TSWLT on TEST_CBO_TSWLT (col_ts_wlt);

ALTER TABLE TEST_CBO_TSWLT  MODIFY (COL_TS_WLT TIMESTAMP(6) with local time zone );

execute DBMS_STATS.GATHER_TABLE_STATS (OWNNAME =>'MYSCHEMA',TABNAME =>'TEST_CBO_TSWLT');

然后,我将数据库NLS参数复制到我的会话中,以简化理解。

select * from nls_session_parameters 
where parameter in ('NLS_DATE_FORMAT','NLS_TIMESTAMP_FORMAT','NLS_TIMESTAMP_TZ_FORMAT');
-->NLS_DATE_FORMAT  DD/MM/RR HH24:MI:SS
-->NLS_TIMESTAMP_FORMAT DD/MM/RR HH24:MI:SSXFF
-->NLS_TIMESTAMP_TZ_FORMAT  DD/MM/RR HH24:MI:SSXFF TZR

ALTER SESSION  SET NLS_DATE_FORMAT = 'DD/MM/RR HH24:MI:SS' ;
ALTER SESSION  SET NLS_TIMESTAMP_FORMAT =  'DD/MM/RR HH24:MI:SSXFF' ;
ALTER SESSION  SET NLS_TIMESTAMP_TZ_FORMAT =  'DD/MM/RR HH24:MI:SSXFF TZR' ;

Test_1没问题

select * from TEST_CBO_TSWLT
where col_date >= '01/01/02 00:00:00'
and col_date < '02/01/02 00:00:00';
--CBO compute a cardinality of 24
--24 rows returned

Test_2是ko

select * from TEST_CBO_TSWLT
where col_ts_wlt>= '01/01/02 00:00:00'
and col_ts_wlt< '02/01/02 00:00:00';
--CBO compute a cardinality of 219
--24 rows returned

Test_3是ko

select * from TEST_CBO_TSWLT
where col_ts_wlt>= '01/01/02 00:00:00,000000000'
and col_ts_wlt< '02/01/02 00:00:00,000000000';
--CBO compute a cardinality of 219
--24 rows returned

我必须使用哪种格式才能在CBO上获得正确的基数?

PS:我使用的查询工具(Business Objects)无法在比较的严格方面指定“to_date”或“cast”等功能,这就是我必须管理caracters的原因。

0 个答案:

没有答案