`
liuhuashan_21
  • 浏览: 5474 次
  • 性别: Icon_minigender_1
  • 来自: 济南
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

关系数据库性能问题--引用

阅读更多

一、任务描述

工作中的一个数据批量任务,涉及到4张基本表和4张业务数据表。
基本表 (Basic Table) 数据量不大,每个表最多几百条记录;业务表 (Transaction Table) 数据量较大,每个表有几十万条记录。

以前的版本使用OO(O/R ?)方式,
(1) SQL查询数据库选出一个业务表的数据,每条记录映射为一个Object。
(2) 循环每个Object,根据属性 查询数据库,取出关联的表数据,映射为Object;依此类推,一步步取出相关数据Object。然后计算并生成结果数据。

这种方案,第一次取出的数据集很大,循环步数很多,而且每一步里面都要涉及到多次数据库查询,速度很慢,处理一个月的上万条数据,都需要几个小时。类似于

代码
  1. Select * from Transact_A where ….   
  2. While(rs.next()){   
  3. a.populate(rs);   
  4.   
  5. If(a…) {   
  6.    Select * from Transact_B where ….   
  7.    If( … ) select * from Basic_B where ….   
  8. }else{   
  9.    Select * from Basic_A where ……   
  10. }   
  11. ….   
  12. }   
<script>render_code();</script>

 

后续版本,我决定采用 Join Table的方式来处理,试图用一个复杂的Big Join Query / View 一次把所有的相关数据记录全都取出来。整个处理过程中,只需要一次数据库查询。

 

代码
  1. Select * from (Transact_A left join Basic_B on ….) inner join Transact_B on .., C, D, E… Where … <  …. > … not exists… a lot of conditions.   
  2.   
  3. While(rs.next()){   
  4. a.populate(rs);   
  5. b.populate(rs);   
  6.   
  7. if(a… b.. ) …   
  8. …   
  9. }   
<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。

代码
  1. 15. 减少对表的查询    
  2. 在含有子查询的SQL语句中,要特别注意减少对表的查询.    
  3.   例如:     
  4.      Slow:   
  5.           SELECT TAB_NAME    
  6.           FROM TABLES    
  7.           WHERE TAB_NAME = ( SELECT TAB_NAME     
  8.                                 FROM TAB_COLUMNS    
  9.                                 WHERE VERSION = 604)    
  10.           AND DB_VER= ( SELECT DB_VER     
  11.                            FROM TAB_COLUMNS    
  12.                            WHERE VERSION = 604)    
  13.   
  14.      Fast:   
  15.           SELECT TAB_NAME    
  16.           FROM TABLES    
  17.           WHERE  (TAB_NAME,DB_VER)    
  18.                = ( SELECT TAB_NAME,DB_VER)     
  19.                    FROM TAB_COLUMNS    
  20.                    WHERE VERSION = 604)    
  21.   
  22.      Update 多个Column 例子:    
  23.      Slow   
  24.            UPDATE EMP    
  25.            SET EMP_CAT = (SELECT MAX(CATEGORY) FROM EMP_CATEGORIES),    
  26.               SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CATEGORIES)    
  27.            WHERE EMP_DEPT = 0020;    
  28.   
  29.      Fast   
  30.            UPDATE EMP    
  31.            SET (EMP_CAT, SAL_RANGE)    
  32.  = (SELECT MAX(CATEGORY) , MAX(SAL_RANGE)    
  33.  FROM EMP_CATEGORIES)    
  34.            WHERE EMP_DEPT = 0020;   
<script>render_code();</script>

 

其中的第8条,我恰好用得上。

代码
  1. 8. 使用DECODE函数来减少处理时间    
  2. 使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表.    
  3. 例如:    
  4.    SELECT COUNT(*),SUM(SAL)    
  5.    FROM EMP    
  6.    WHERE DEPT_NO = 0020    
  7.    AND ENAME LIKE ‘SMITH%’;    
  8.    SELECT COUNT(*),SUM(SAL)    
  9.    FROM EMP    
  10.    WHERE DEPT_NO = 0030    
  11.    AND ENAME LIKE ‘SMITH%’;    
  12. 你可以用DECODE函数高效地得到相同结果    
  13. SELECT COUNT(DECODE(DEPT_NO,0020,’X’,NULL)) D0020_COUNT,    
  14.         COUNT(DECODE(DEPT_NO,0030,’X’,NULL)) D0030_COUNT,    
  15.         SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL,    
  16.         SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SAL    
  17. FROM EMP WHERE ENAME LIKE ‘SMITH%’;    
  18. 类似的,DECODE函数也可以运用于GROUP BY 和ORDER BY子句中.   
<script>render_code();</script>

 

正好用来更新 parent 纪录中关于 child的统计字段。以前我这么写,

代码
  1. update parent p   
  2. set    
  3. balance_1 = (select sum(amount) from child c where  c.parent_id = p.id and type in (12))    
  4. balance_2 = (select sum(amount) from child c where  c.parent_id = p.id and type in (34))   
  5. where …   
<script>render_code();</script>

 

现在我这么写,

代码
  1. update parent p   
  2. set    
  3. (balance_1, balance_2) = (   
  4. select    
  5. sum(decode(type, 1, amount, 2, amount, null)) as balance_1,   
  6. sum(decode(type, 3, amount, 4, amount, null)) as balance_2,   
  7. from child c where  c.parent_id = p.id)    
  8. where …   
<script>render_code();</script>

 

三 临时表
优化了半天,瓶颈在于对其中一个Big View的多次使用上。只好用空间换时间,把这个多次使用的View先放到临时表里面。
业务逻辑有这样的匹配逻辑,选择最符合条件的数据,其他的数据不用。

代码
  1. Select * from   
  2. (Select * from temp    
  3. where …   
  4. order by column_1, column_2, column_3) t   
  5. where t.rownum = 1  -- 只选择排在最前面的一条   
<script>render_code();</script>

 

如果直接用上面这段SQL来过滤temp数据,比较麻烦。我干脆又在temp里面多加了一个额外字段match_level, 专门用来存放匹配级别。
创建临时表数据的时候,直接生成这个match_level。

代码
  1. Insert into temp   
  2. select    
  3. big_view.*,   
  4. decode(column_1,  … ) || decode(column_2, …) || decode(column_3, …) as match_level   
  5. from big_view where …   
<script>render_code();</script>

 

这里把多个column排序结果综合到一个字段里面,便于后面的比较。
于是,我就可以用一条相对比较简单的SQL删除掉 不是最佳匹配的纪录。

代码
  1. delete temp   
  2. where exists(   
  3. select * from   
  4. (select id, max(match_level) from temp t group by id having count(*) > 1)  t   
  5. 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.

分享到:
评论

相关推荐

    VFP数据库系统Visual-FoxPro数据库和表的高级应用.pdf

    第四章 数据库和表的高级应用 4.1 数据库的使用 4.2 数据库的高级应用 4.3 设置表属性 4.4 建立表间的关系 4.5 使用多个表 4.1 数据库的使用 4.1.1 向数据库添加数据表 向数据库添加表有两种方法:菜单方式和命令...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...

    数据库资料

    主要包含最基础的数据库语句,很适合初学者,目标使用企业管理器创建数据库表设置表的主键、外键和建立表之间的关系为表增加约束数据完整性 数据完整性 数据存放在表中 “数据完整性的问题大多是由于设计引起的” ...

    金属材料标准的应用数据库MtrRvw

    2.1.2 试验特征之间的逻辑关系通过试验特征对其它试验特征的要求值和测量值的引用,以及数据库表、查询和程序模块的设计表现。 2.1.3 将标准文件整合为“文件汇编” 2.2 试验标准的数据化 2.2.1 数据化的通用方法: ...

    网上购物系统数据库设计.doc

    除了性能以外的问题,就是维护的问题了,数据库应该易于维护。这包括只存储数量有 限的(如果有的话)重复性数据。如果有很多的重复性数据,并且这些数据的一个实例 发生一次改变(例如,一个名字的改变),这个...

    基于图数据库存储引擎的CMDB系统.pdf

    关系数据库与图数据库区别 关系数据库将数据存储在具有固定结构 (架构) 的表中, 每列具有名称、 类型、长度、约束等。 表与表之间的引用通过将一个表的主键作为另一个表 的重复外键来实现。 对于多对多的关系...

    SQL Server 2008数据库设计与实现

    通过将理论融入数据库实践,清晰地讲解了关系型数据库的设计原则,完整地展示了如何进行良好的关系型数据库设计,深入揭示了SQL Server 2008的技术细节。  本书浓缩了作者作为SQL Server数据库架构师多年来丰富的...

    商业银行信贷管理系统的数据库设计要点(1).doc

    数据库要能正确地描述信贷业务的信息、过程、关系,错误的信息描述将会带来 不可预知的问题,所以,在设计表时,要多与银行信贷业务人员、管理人员、高层领导沟通 ,从多个角度正确理解业务对象的信息内容、用途和关系,...

    Java数据库编程宝典3

    第1章 关系型数据库 1.1 理解关系型数据库管理系统 1.1.1 关系模型 1.1.2 Codd法则 1.1.3 表、行、列和关键字 1.1.4 主键 1.1.5 外键 1.1.6 关系 1.1.7 视图 1.1.6 范式化 1.2 高级语言 1.2.1 结构化...

    数据库设计规范化反规范化.doc

    实体关系图是表示实体及实体间关系的图解形式,是数据库设计的初步.常简称E- R图 (3).实体关系图的表现形式: 实体:矩形框 属性:椭圆 关系:菱形框 2.实体图示例 3.实体-关系图(E-R)示例 4.同类实体间可能存在关系 5.二...

    3-AnnetPACS数据库设计说明.doc

    数据库表间关系如下图: 4数据库详细设计 4.1 表Patient "编号"字段名称 "字段类 "字段"字段限制 "字段说明 " " " "型 " " " " "1 "PatientID "nvarcha"20 "主键,不允许为空 "病人ID号 " " " "r " " " " "2 "HISID ...

    数据库设计说明书模板

    【说明】数据库视图、同义词、物化视图、DBLink的建设原因,并阐述是否存在性能问题 存储空间规划 【说明】 1.估算系统的初始数据量,增长量及周期,初始数据空间需求 2.是否建立独立的表空间,索引空间,临时表...

    新版Android开发教程.rar

    ----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 2 开放手机联盟 --Open --Open --Open --Open Handset Handset Handset Handset Alliance ...

    软件数据库设计模板.docx

    数据库环境说明 描述本设计需采用的数据库系统,设计工具,编程工具以及配置等 逻辑结构设计 数据库设计人员根据需求文档,创建与数据库相关的那部分实体关系图软件数据库设计模板全文共6页,当前为第5页。...

    数据库安全性设计.doc

    在关系数据库中,可以根据实际的需求为特定的用户定义特定的视图。让表中的一部 分数据只对一部分特定的用户可见。如果一些数据是保密的,就可以使用视图把这些数 据隐藏起来,使没有获得授权的用户不能看到这些...

    数据库设计参考规范.doc

    数据库设计规范化的五个要求 数据库逻辑设计是优化关系数据库的核心。而数据库设计的规范化则是这个核心的核 心。一个规范化的逻辑数据库,可以为数据库管理员优化数据库和应用程序性能打下坚 实的基础。相反,若...

    使用MySQL设计企业OA系统的数据库课程设计文档

    根据提供的引用内容,这个文件主要总结了一个企业OA系统的数据库设计项目。项目的目标是设计一个能够帮助企业进行高效信息管理和协作的办公自动化系统。该系统使用MySQL作为数据库管理系统,因为MySQL具有高性能、...

    浅谈数据库设计.doc

    所谓需求是指用户对软件的功能和性能的要求, 就是用户希望软件能做什么事情,完成什么样的功能,达到什么性能。需求分析是数据 库设计最基础的工作,如果这个阶段的工作不准确或有误,那么后面几个阶段的任务就 会...

    Java数据库编程宝典2

    第1章 关系型数据库 1.1 理解关系型数据库管理系统 1.1.1 关系模型 1.1.2 Codd法则 1.1.3 表、行、列和关键字 1.1.4 主键 1.1.5 外键 1.1.6 关系 1.1.7 视图 1.1.6 范式化 1.2 高级语言 1.2.1 结构化...

Global site tag (gtag.js) - Google Analytics