Oracle数据库设计类型选择错误的隐患

数据类型不准确的一个隐患,下面来构造一张表存日期字段,一个存varchar2,一个存date,做一个测试。之前也写过两篇blog:

1.字段类型设计与实际业务不符引发的问题1

2.字段类型设计与实际业务不符引发的问题2

SQL> drop table test purge;

SQL> create table test as select

to_char(to_date(‘2014-01-01‘,‘yyyy-MM-dd‘)+rownum,‘yyyymmdd‘) s_date,

to_date(‘2014-01-01‘,‘yyyy-MM-dd‘)+rownum d_date

from all_objects;

SQL> create index ind_t_sdate on test(s_date) nologging;

SQL> create index ind_t_ddate on test(d_date) nologging;

SQL> exec dbms_stats.gather_table_stats(user,‘test‘,cascade => true);

SQL> set timing on

SQL> set autotrace traceonly

SQL> select * from test where s_date between ‘20140201‘ and ‘20140222‘;

已选择22行。

已用时间:  00: 00: 00.00

执行计划

----------------------------------------------------------

Plan hash value: 953148778

-------------------------------------------------------------------------------------------

| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT            |             |     3 |    51 |     3   (0)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| TEST        |     3 |    51 |     3   (0)| 00:00:01 |

|*  2 |   INDEX RANGE SCAN          | IND_T_SDATE |     3 |       |     2   (0)| 00:00:01 |

-------------------------------------------------------------------------------------------

--可以看到CBO评估出来的行数是3,明明返回的是22

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access("S_DATE">=‘20140201‘ AND "S_DATE"<=‘20140222‘)

统计信息

----------------------------------------------------------

1  recursive calls

0  db block gets

7  consistent gets

0  physical reads

0  redo size

944  bytes sent via SQL*Net to client

349  bytes received via SQL*Net from client

3  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

22  rows processed

SQL> select * from test

where d_date between to_date(‘20140201‘, ‘yyyymmdd‘) and

to_date(‘20140222‘, ‘yyyymmdd‘);

已选择22行。

已用时间:  00: 00: 00.00

执行计划

----------------------------------------------------------

Plan hash value: 112387541

-------------------------------------------------------------------------------------------

| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT            |             |    23 |   391 |     3   (0)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| TEST        |    23 |   391 |     3   (0)| 00:00:01 |

|*  2 |   INDEX RANGE SCAN          | IND_T_DDATE |    23 |       |     2   (0)| 00:00:01 |

-------------------------------------------------------------------------------------------

--可以看到CBO评估出来基本是准确的。

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access("D_DATE">=TO_DATE(‘ 2014-02-01 00:00:00‘, ‘syyyy-mm-dd hh24:mi:ss‘)

AND "D_DATE"<=TO_DATE(‘ 2014-02-22 00:00:00‘, ‘syyyy-mm-dd hh24:mi:ss‘))

统计信息

----------------------------------------------------------

1  recursive calls

0  db block gets

7  consistent gets

0  physical reads

0  redo size

944  bytes sent via SQL*Net to client

349  bytes received via SQL*Net from client

3  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

22  rows processed

    总结:虽然这两条SQL消耗的资源是一样的,但SQL1的评估结果不对,在多表关联的时候,这个绝对是个隐患,非常容易导致执行计划走错。除了以上的几个原因之外,还存在的问题是用varchar2存date会造成N多的存储格式,曾经看到过一个情况,日期格式五花八门(有年月日,年月日 小时,年月日 小时,分钟),有中英文的:,有全角、半角,有null,甚至undefine(大概是从js传过来的)。且造成索引建了用不上,不得已改数据类型,光写转换的脚本就花了一天多的时间。

时间: 2024-11-05 19:03:32

Oracle数据库设计类型选择错误的隐患的相关文章

mysql_数据库设计类型选择及优化

数据库设计原则: a,更小的通常更好. 应该尽量使用可以正确存储数据的最小数据类型.如只要存储0-200,tinyint unsigned更好 b,简单就好 简单的数据类型的操作需要更少的cpu周期.同时后期优化也更为容易. c,尽量避免使用null mysql在建立索引,优化过程对null需要做特殊处理,耗费额外资源.非特殊情况,避免使用null. 数据类型常识 一,整数类型 根据存储空间: TINYINT SMALLINT MEDIUMINT INT BIGINT 存储空间位数n 8 16

Oracle数据库date类型与Java中Date的联系与转化

以下是对Java中的日期对象与Oracle中的日期之间的区别与联系做点说明,以期对大家有所帮助.new Date():分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒),就是系统当前.new Date(long date) : 分配 Date 对象并初始化此对象,以表示自从标准基准时间    (称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数.long getTime() :返回自 1970 年 1 月 1 日 00:00

中断ORACLE数据库关闭进程导致错误案例

昨晚下班的时候,我准备关闭本机的虚拟机上的ORACLE数据库后准备下班,但是由于我SecureCRT开了多个窗口,结果一不小心,疏忽之下在一个生产服务器上执行了shutdown immediate命令,大概过了6到7秒,发现该命令还没有响应,我才发现我这个命令执行错了服务器.一惊之下,想都没有想直接CTRL+C想中断这个操作. 如下所示: SQL> shutdown immeidate; SP2-0717: illegal SHUTDOWN option SQL> shutdown immed

oracle数据库语言类型

oracle数据库语言类型一般分为五大类型 1 DDL(data definition language)数据定义语言 CREATE TABLE :创建表 ALTER TABLE :修改表 DROP TABLE:删除表(对表整体删除,表结构也不存在了) TRUNCATE TABLE :删除表(删除所有行,表结构还在) 2 DML(data Manipulation language)数据操纵语言 INSERT :插入 UPDATE :更新 DELETE:删除 3 DQL(Data Query L

Microsoft.mshtml.dll 添加引用及类型选择错误问题解决办法

在比较早的文章中,提到使用 Microsoft.mshtml.dll 进行模拟浏览器点击的例子. 1.添加引用的问题 一般在开发环境下会在三个地方存有microsoft.mshtml.dll文件.所以在添加引用时,也会出现三个看似一样的项.对于开发者来说,引用其中任何一个都不会影响到正常的开发.但问题会出在软件发布之后!在客户的机子上运行时,通常会提示文件的签名不正确,无法加载.解决的方法就是删除现在对mshtml引用.重新选择正确引用.就是选最下面那个.路径是:X:\Program Files

Oracle数据库设计第三范式

一.数据库设计范式及其意义和不足 数据库的设计范式是数据库设计所需要满足的规范,数据库的规范化是优化表的结构和优化把数据组织到表中的方式,这样使数据更明确,更简洁.实践中,通常把一个数据库分成两个或多个表并定义表之间的关系以做到数据隔离,添加.删除和修改某个字段只需要在一个表中进行,接着可以通过定义的关系传递到数据库中剩余的表中(和分层思想的意义所在很相似).这样我们可以消除很多错误或垃圾数据出现的机会并减轻更新信息所必要的工作量. 目前,主要有六种范式:第一范式.第二范式.第三范式.BC范式.

oracle数据库数值类型

---恢复内容开始--- 内容摘自网络 Oracle的数值类型有int,number,float,decimal,numberic等. NUMBER类型 定义 定义格式NUMBER (precision,scale) precision表示数字中的有效位(从左边第一个不为0的数算起,小数点和负号不计入有效位数),取值范围为[1-38]默认38. scale表示精确到多少位,取值范围为[-84-127],默认值为0.大于零时,表示数字精确到小数点右边的位数:小于零时,将把该数字取舍到小数点左边的指

Oracle数据库设计小细节

1. 如果使用PowerDesigner此类工具,注意将工具的导出的SQL语句中对于表的双引号去掉. 2. 建表和建字段的时候,不同单词之间使用下划线分隔,比如 REC_ID 3. Oracle中数值类型字段,应该确定精度,利用MBG反向生成的时候,可以确定是Integer还是BigDecimal. 4. Oracle中的nvarchar2和nvarchar2在被MBG反向生成的时候,会被识别为Object类型,建议使用varchar2. ----------------------------

关于Oracle数据库字符集的选择

如果数据库只在中国地区使用,数据库字符集选择ZHS16GBK或者常用中文字符集,如果不确定,就推荐使用AL32UTF8 国家字符集就选择: AL16UTF16 字符集一旦设定,不允许修改,修改可能出现乱码问题.Default Language和Default Territory默认即可.