
update pub_accountinginfo p
set p.extfld1 = '20161105_990007_01'
where p.subjectcode = '211010000001'
and p.pltdate between to_date('20161103162000', ‘YYYYMMDDHH24MI' )
and ('20161104162000‘,‘YYYYMMDDHH24MI')
and p.extfld1 is null
and exists
(select 1
from pub_accountinginfo s
where s.subjectcode = '301070000005'
and p.pltdate between to_date('20161103162000', ‘YYYYMMDDHH24MI' )
and ('20161104162000‘,‘YYYYMMDDHH24MI')
and s.accountserial = p.accountserial)
再创建pltdate 字段索引或者( pltdate,subjectcode )组合索引,Oracle将按新建索
引进行访问,性能得到极大提升。
该案例实际上也是业内普遍存在的日期数据不用Date类型而用数字、字符类型进行表示的
典型负面案例。用数字、字符类型表示日期数据不仅存在该案例的日期数据转换带来的无法使
用索引问题;还存在无法合理使用日期函数和日期表达式的计算问题,例如通过last_day(日
期数 据)可计算出该日期数据的月末 最后一天;还有无法进行日 期数据校验问题,例如
20240230可输入到数字或字符字段中而无法输入到Date字段中;还可能误导Oracle优化器产生
错误的执行计划。例如年终决算时需查询20231231至20240101之间的数据,用Date类型表示日
期数据,Oracle将计算为间隔一天,优化器会合理使用索引。如果用数字、字符类型表示日期
数据,则计算为间隔20240101 – 20231231 = 8870天,很可能误导优化器走全表扫描了。
因此,如果我作为开发和应用DBA,在数据库逻辑设计中,我一定会要求开发团队按事物
本身规律合理设计字段类型,该数字就数字类型,该字符就字符类型,该日期就Date类型。为
什么业内那么多开发人员非要拧巴着将日期数据设计成数字或字符类型,然后转换来、转换
去,最后折腾出那么多问题呢?实在令我费解。
数据库逻辑内容和方法
数据库逻辑设计不仅包括上述案例展示的正确设计字段类型内容,而且还包括3个范式的
基本规范。如果我作为开发DBA,我会让我的团队尽量遵循数据库规范化设计理论,至少不会
在一个字段中用逗号等隔离符存储信息,也不会让SQL语句中出现大量substr、trim等函数,
因为不仅会导致无法使用索引问题,而且问题根源就是数据库设计没有遵循第一范式(1NF)
即确保字段信息的原子化。例如,在《陪客户过年关的二三事》一文的故事三就是数据库设计
者将多段业务信息都塞到一个LOB字段中,导致不得不进行多次大表连接的严重性能问题。
在数据库逻辑设计中我还会大力推荐主外键技术的运用,因为这样不仅能确保业务数据的
一致性 ,而且 是实施Reference分 区、Sharding架 构等技 术的 基 础。我还会 强调check、
constraint等技术的运用,而不是把数据质量控制都依托应用软件层实现,因为这样一方面可
相关文档
评论