一、任务描述
工作中的一个数据批量任务,涉及到4张基本表和4张业务数据表。
基本表 (Basic Table) 数据量不大,每个表最多几百条记录;业务表 (Transaction Table) 数据量较大,每个表有几十万条记录。
以前的版本使用OO(O/R ?)方式,
(1) SQL查询数据库选出一个业务表的数据,每条记录映射为一个Object。
(2) 循环每个Object,根据属性 查询数据库,取出关联的表数据,映射为Object;依此类推,一步步取出相关数据Object。然后计算并生成结果数据。
这种方案,第一次取出的数据集很大,循环步数很多,而且每一步里面都要涉及到多次数据库查询,速度很慢,处理一个月的上万条数据,都需要几个小时。类似于
代码
- Select * from Transact_A where ….
- While(rs.next()){
- a.populate(rs);
-
- If(a…) {
- Select * from Transact_B where ….
- If( … ) select * from Basic_B where ….
- }else{
- Select * from Basic_A where ……
- }
- ….
- }
<script>render_code();</script>
后续版本,我决定采用 Join Table的方式来处理,试图用一个复杂的Big Join Query / View 一次把所有的相关数据记录全都取出来。整个处理过程中,只需要一次数据库查询。
代码
- Select * from (Transact_A left join Basic_B on ….) inner join Transact_B on .., C, D, E… Where … < …. > … not exists… a lot of conditions.
-
- While(rs.next()){
- a.populate(rs);
- b.populate(rs);
-
- if(a… b.. ) …
- …
- }
<script>render_code();</script>
一部分 Business Logic (条件比较等)移动到SQL里面,代码的可读性变差,运行速度提高。
由于业务逻辑的复杂性,一条SQL很难恰好选出需要处理的数据,为了最大限度的减少不必要的数据,有些比较大的复合View还被多次引用。
几千条数据,这条SQL工作还好,几秒钟、十几秒钟就返回结果集;几万条数据,这条SQL需要几分钟才能够返回;几十万条数据,运气好,10多分钟、几十分钟返回,运气不好,就干脆不返回了。
二 SQL Optimization
Oracle网站有Performance Tuning的PDF文档,详细介绍了语句置换,hint, index, explain plan, SQL Trace等方法。
这里有一篇比较全的翻译的SQL调优文章,
http://www.chinaunix.net/jh/19/214182.html
其中的第15条明确说明,SQL中的 = 操作符 支持 Tuple元组操作,这个 = 可以用来给一个元组Tuple赋值,也可以比较两个元组Tuple。
代码
- 15. 减少对表的查询
- 在含有子查询的SQL语句中,要特别注意减少对表的查询.
- 例如:
- Slow:
- SELECT TAB_NAME
- FROM TABLES
- WHERE TAB_NAME = ( SELECT TAB_NAME
- FROM TAB_COLUMNS
- WHERE VERSION = 604)
- AND DB_VER= ( SELECT DB_VER
- FROM TAB_COLUMNS
- WHERE VERSION = 604)
-
- Fast:
- SELECT TAB_NAME
- FROM TABLES
- WHERE (TAB_NAME,DB_VER)
- = ( SELECT TAB_NAME,DB_VER)
- FROM TAB_COLUMNS
- WHERE VERSION = 604)
-
- Update 多个Column 例子:
- Slow
- UPDATE EMP
- SET EMP_CAT = (SELECT MAX(CATEGORY) FROM EMP_CATEGORIES),
- SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CATEGORIES)
- WHERE EMP_DEPT = 0020;
-
- Fast
- UPDATE EMP
- SET (EMP_CAT, SAL_RANGE)
- = (SELECT MAX(CATEGORY) , MAX(SAL_RANGE)
- FROM EMP_CATEGORIES)
- WHERE EMP_DEPT = 0020;
<script>render_code();</script>
其中的第8条,我恰好用得上。
代码
- 8. 使用DECODE函数来减少处理时间
- 使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表.
- 例如:
- SELECT COUNT(*),SUM(SAL)
- FROM EMP
- WHERE DEPT_NO = 0020
- AND ENAME LIKE ‘SMITH%’;
- SELECT COUNT(*),SUM(SAL)
- FROM EMP
- WHERE DEPT_NO = 0030
- AND ENAME LIKE ‘SMITH%’;
- 你可以用DECODE函数高效地得到相同结果
- SELECT COUNT(DECODE(DEPT_NO,0020,’X’,NULL)) D0020_COUNT,
- COUNT(DECODE(DEPT_NO,0030,’X’,NULL)) D0030_COUNT,
- SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL,
- SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SAL
- FROM EMP WHERE ENAME LIKE ‘SMITH%’;
- 类似的,DECODE函数也可以运用于GROUP BY 和ORDER BY子句中.
<script>render_code();</script>
正好用来更新 parent 纪录中关于 child的统计字段。以前我这么写,
代码
- update parent p
- set
- balance_1 = (select sum(amount) from child c where c.parent_id = p.id and type in (1, 2))
- balance_2 = (select sum(amount) from child c where c.parent_id = p.id and type in (3, 4))
- where …
<script>render_code();</script>
现在我这么写,
代码
- update parent p
- set
- (balance_1, balance_2) = (
- select
- sum(decode(type, 1, amount, 2, amount, null)) as balance_1,
- sum(decode(type, 3, amount, 4, amount, null)) as balance_2,
- from child c where c.parent_id = p.id)
- where …
<script>render_code();</script>
三 临时表
优化了半天,瓶颈在于对其中一个Big View的多次使用上。只好用空间换时间,把这个多次使用的View先放到临时表里面。
业务逻辑有这样的匹配逻辑,选择最符合条件的数据,其他的数据不用。
代码
- Select * from
- (Select * from temp
- where …
- order by column_1, column_2, column_3) t
- where t.rownum = 1 -- 只选择排在最前面的一条
<script>render_code();</script>
如果直接用上面这段SQL来过滤temp数据,比较麻烦。我干脆又在temp里面多加了一个额外字段match_level, 专门用来存放匹配级别。
创建临时表数据的时候,直接生成这个match_level。
代码
- Insert into temp
- select
- big_view.*,
- decode(column_1, … ) || decode(column_2, …) || decode(column_3, …) as match_level
- from big_view where …
<script>render_code();</script>
这里把多个column排序结果综合到一个字段里面,便于后面的比较。
于是,我就可以用一条相对比较简单的SQL删除掉 不是最佳匹配的纪录。
代码
- delete temp
- where exists(
- select * from
- (select id, max(match_level) from temp t group by id having count(*) > 1) t
- where temp.id = t.id and temp.match_level < t.match_level)
<script>render_code();</script>
处理一个月的数据,上万条记录的情况下,上面这两条insert和 delete执行时间加起来在10 -- 20秒左右。后面的一个Big Query就可以用这个temp table直接把恰好要使用的数据取出来,10秒左右就可以返回结果集(几万条)。处理这个结果集的时间,几分钟左右。
处理24个月的几十万条数据,需要几十分钟。速度提高了几十倍。
既然为了速度,用了这么多vendor native SQL feature, Big Join, temp table, 已经没有移植性可言,为什么不干脆用PL/SQL?
我对PL/SQL语法不熟悉,只是尽量把条件判断过滤放到SQL里面,而重要的计算公式部分(还是比较复杂的)在Java里面处理。我觉得,SQL即使带一点Native feature,也应该比Stored Procedure容易移植。
四 对象数据库
关系数据库号称 更快,支持更复杂的数据类型和关系,数据间的关联查询更快。
不算那些Java, C++等Object的存储工具,只算那些称得上DB的,开源的Object Database有db4object, OZONE, GigaBase(Object Relational Database)等。
(Berkeley DB勉强算得上Object Database?)
存储空间和性能还无法和商业数据库比。不像关系数据库,有了MaxDB, Ingres, PostgreSQL等比较成熟的开源关系数据库。
商业对象数据库挺多,这里就不罗列了。我看的资料比较的多的是Objectivity/DB和Intersystems Cache’。
http://www.objectivity.com
http://www.intersystems.cn
http://www.intersystems.com
两者都号称大数据量、高并发、高性能。通过看过的文档和资料,我更看好Cache’一些。似乎Cache’ 更快,更便宜,支持关系模型更好。Cache’号称 后关系数据库 Post Relational Database。当然,Objectivity是purer Object Database,面向对象特性也许更多一些。
关于对象数据库性能,有两种相反的说法。
1. 对象数据库 比 关系数据库 快
引用
原文
http://www.cnblogs.com/xgchang/archive/2004/12/05/26474.html
⑷性能的比较
ODBMS和RDBMS产品数据存取性能的差别已按通用测试标准验证过了。SUN公司的Riok Cattell等人著的“对象数据库评估”(1991年对象世界会议文集)已对四个ODBMS产品:Objectivity,Objectstore,Ontos,Versant以及两个RDBMS产品:Sybase和Ingress进行了测试。一般说来,对于“冷”数据存取(对磁盘数据库存取)ODBMS比RDBMS平均快5倍;对于“热”数据存取(在内存中的数据库存取)要快30倍,对于“热导航”(在内存中对某一给定的对象访问与之相联系的所有对象)ODBMS任何一个产品都比RDBMS的每一个产品性能要高出三个数量级。
Objectivity/DB自己的Bench Mark文章这样写,在小数据量下,RDBMS(Oracle)更快,数据量越大,Objectivity就会比RDBMS快的越多。
2. 对象数据库 比 关系数据库 慢
引用
原文
http://www.fic.se/MScThesis.Frost.Beta.pdf
Multi-dimensional and relational data warehouses have problems.
expressing complex data types. Object orientation on the other hand deal with complex
data types but lacks in performance on the database technology side.
…
object-oriented database management systems (OODBMS) the poor performance on ad- hoc queries.
…
object-oriented data warehouse still face the problem of ad-hoc query performance on large datasets, a problem which multi-dimensional, relational and hybrid techniques overcomes.
…
分享到:
相关推荐
Oracle9i和Oracle10g引入了许多新功能,如提高性能、增强可靠性、扩展性、安全管理,并支持网格计算,简化数据库管理和调整,以适应不断变化的业务需求。 综上所述,Oracle数据库提供了强大且灵活的数据管理解决...
《数据库原理》第三章主要探讨的是关系数据库系统RDBS,这一章的作业涉及到了数据库设计的基本概念,包括实体、属性、实体之间的联系以及数据库完整性。以下是对这些知识点的详细阐述: 1. **关系数据模型**:关系...
6. **数据库性能优化**:包括查询优化、存储过程使用、合理分区、适当的数据类型选择、索引策略等,都是数据库性能优化的重要方面。 7. **数据库安全**:涉及用户权限管理、数据加密、审计日志等,确保数据的安全...
在《广工数据库实验报告-SQL语言的使用.doc》中,会详细讲解SQL(结构化查询语言),它是与关系型数据库交互的标准语言。SQL包括数据查询、数据插入、更新和删除,以及创建和修改数据库结构等功能。通过学习SQL,...
报告中可能引用了相关数据库理论书籍、学术论文和其他技术资料,为设计决策提供了理论依据。 ### 0.5 术语与缩写解释 为了确保阅读的清晰性,报告会解释关键的数据库术语和缩写,使非专业读者也能理解报告的内容。...
### 对象-关系数据库之间的映射 ...总之,对象-关系数据库映射不仅是技术问题,也是设计哲学的体现。它要求开发者在理解面向对象和关系数据库各自优势的基础上,寻找二者间的平衡点,以构建高效、可维护的应用系统。
这意味着表中存在一个字段,该字段引用同一表中的其他行,形成一种自我指涉的关系。例如,一个员工表可能有一个“上级ID”字段,指向其直接上级的员工ID。 2. **递归查询**:为了读取这些树状数据,SQL提供了递归...
4. 数据库优化:通过合理设计关系图,避免冗余数据,提高查询性能,同时保证数据的一致性和安全性。 5. 实践案例分析:通过实际的案例,练习创建数据库关系图,设置各种约束,并进行调整,以满足具体需求。 在完成...
【数据库应用技术】和【关系数据库设计】是本文件的核心主题。关系数据库设计涉及如何有效地组织和存储数据,确保数据的准确性和一致性。这通常基于规范化理论,它是一套指导原则,帮助设计师创建科学合理的关系模式...
逻辑模型如关系模型,是数据库实际操作的基础,其中SQL语言是关系数据库的标准语言;物理模型则涉及数据在存储设备上的布局和访问方法。 关系模型是目前最广泛使用的数据模型,其核心是关系,即二维表格。书中会...
通过索引优化、查询重构和适当的数据分区策略,可以提升数据库性能。 9. 源码部分:这个项目包含源码,可能涉及前端界面的开发,如使用HTML、CSS和JavaScript构建用户界面,以及后端的编程,如PHP、Java或Python...
主键的选择对数据库性能有着直接影响。通常情况下,主键可以是无物理意义的数字序列,由系统自动递增生成;也可以是有物理意义的字段或字段组合。当主键是字段组合时,建议字段的数量不要过多,以避免增加索引的开销...
### HIBERNATE - 符合Java习惯的关系数据库持久化:深入解析与实践 #### 一、概述 Hibernate是Java领域内最受欢迎的对象关系映射(ORM)框架之一,它简化了Java应用程序与关系型数据库之间的交互,使得开发人员...
表与表之间可以通过键(如主键和外键)建立关联,形成关系,使得数据能够相互引用。 SQL(Structured Query Language)是操作关系型数据库的标准语言,你将在课程中学习如何使用SQL进行数据查询、插入、更新和删除...
- **引用多个数据库**:可以同时打开并操作多个数据库,通过`OPEN DATABASE`命令打开新的数据库,不会关闭已打开的数据库。当打开多个数据库时,最后打开的数据库将成为当前数据库。 3. **设置表属性**:这部分未...
8. 关系数据库操作: - 常见的关系操作:选择、投影、连接、除、并、交、差等。 - 数据操作:查询、增加、删除、修改。 9. 关系完整性约束: - 实体完整性:主键不允许为空。 - 参照完整性:外键关联主键,保证...
在面向对象设计的基础上,我们将类和对象转换成关系数据库的表结构。例如,物资类可能对应“物资”表,包含物资ID、名称、规格、供应商ID等字段;库存类对应“库存”表,记录每种物资的库存量和状态。 **第 4 章 ...
10. **性能优化**:通过查询优化、索引优化、存储过程、分区等手段提升数据库性能。例如,分析SQL执行计划,调整JOIN顺序,或创建覆盖索引来优化查询。 东南大学的这个视频教程将涵盖这些基础知识,并可能深入到更...
对象-关系数据库之间的映射是现代软件开发中的一个重要议题,特别是在使用对象技术(如Java)与关系数据库结合的场景下。对象技术强调耦合、聚合和封装,而关系数据库则是基于数学的集合论原理,两者理论基础不同,...
这份文档,即“XXX有限公司 数据库结构设计”,详细阐述了数据库从概念模型到逻辑模型再到物理实现的过程,旨在确保数据的有效性和系统性能。 1. **前言** - **目的**:该文档的主要目的是为了规范和指导数据库的...