数据库操作中是什么在影响系统的性能

原创 2015年07月08日 11:20:15

前言

    注:这里讨论的场景在于MIS,OA一类的系统

   大部分同学在看到这个问题的时候,第一反应是糟糕的SQL语句,没有加索引,这甚至已经成为一种惯性思维。 
   当发现性能出问题的时候,一般都会想到加个索引,或者改造下连接方式,去掉“not exists”诸如此类,但效果往往不太理想,或过一段时间后,效果又不理想了,此时,一般大家都会觉得问题在于自己还不是大神。

正文

   今天给大家分享的就是:为了提高性能,不是大神的我们还有多少方法可以采取? 
   性能有三大杀手:1)糟糕的SQL使用;2)糟糕的数据结构;3)糟糕的业务模型 
   下面举一个实际的例子,在EPO物资采购系统中的需求跟踪功能中,可以查询到所有历史提交的需求申请单。查询包含从需求申请->需求受理->订单->验收入库->通知领用->发放完成所有环节的状态。最初的做法是通过join将需求表、需求受理表、订单表、验收表、领用通知表和发放表连接起来形成一张视图。当数据量小的时候,看起来一切都是那么的完美,但是后来就不那么美好了。于是,后来我们采取了一系列的优化。

阶段一:物化视图

   当join的时候,问题出现在join的计算过程,数据量大了,计算耗费就会大,性能便会下降。不过,当问题来的那天,对于这种问题,大家是非常坦然的面对,做一张物化视图就可以了,每天晚上计算一下,第二天查询物化视图即可。利用原生的SQL功能,物化视图,对于大家来说手到擒来,投入低,收益高,效果立竿见影。 
   物化视图:牺牲实时性,牺牲存储空间,换取性能提升。

阶段二:改变数据结构

   随着数据量加大,我们发现,物化视图的计算越来越慢,虽然是放到晚上,但是随着大家都认识到物化视图可以解决问题,大批量开始使用物化视图,且都放到晚上,滥用的程度甚至都惊动了DBA,晚上的DB负荷居然超过白天的业务高峰运行期。 
   这个场景下的物化视图隐藏的一个问题,就是会重复计算那些永远不会发生变化的数据。比如,有一张2010年的需求单,申请的是电脑,公司规定电脑4年报废,如果我们在2015年跑物化视图时,那张需求单对应到的数据,就永远不会变化;但在每次物化过程这张需求单都会被join到视图中,而join的过程又会产生计算花费。 
   此时我们要做的就是通过数据结构的改变,干掉那些无效的计算。此时会有多种选择,分离历史数据、实体化表等。我们采取的是实体化表的方式,实体化表上会对需求单进行区分,比如说刚刚提到的报废的需求单或领用完成的需求单,这类需求单是再也不会发生改变的,我们给予不会变化标示。而对于那些还未领用完成的需求单,我们标示为待计算,对于那些待计算的需求单我们每天晚上重新计算一次,删除原有数据,填充最新数据。在目前的数据情况下,待计算的需求单占总单的5%以内,相比之前的方式我们至少省去了95%的无效计算过程。 
   改变数据结构:牺牲存储空间,干掉无效计算过程,从而有效降低数据库负荷。

阶段三:优化业务模型

   需求跟踪中有一个查询条件是物料名称,对于这类文本型的查询条件,99%的同学选择都是“like %XYZ%”,但只有一半的同学知道,这种写法使用不到索引,这一半同学中又有99%的同学都会认为这是没有办法的。确实,在技术上99%的人都想不到办法,在技术上这个问题是无解的,因为我们都不是大神。不过可以分享给大家的是,这不是一个错误的SQL写法,而是一个糟糕的业务模型。 
   比如说,我们通过后台可以分析出,大家喜欢用“电脑”、“主机”这类关键字,而输入“电脑”在我们物料库中对应肯定是“平板电脑”、“笔记本电脑”,“主机”对应的一定是“电脑主机”,我们在后台通过将“电脑”转化为“平板电脑”、“笔记本电脑”、“电脑主机”,“主机”转化“电脑主机”,便可以使用“like 电脑主机%”、“like 平板电脑%’、”like 笔记本电脑%”。通过业务模型的优化,再选择合适的SQL语句。上面例子中,80%的查询条件,都可以在后台转化为“XYZ%”的方式,进而可以使用到了大家耳熟能详的索引。 
   优化业务模型:通过运营数据分析,优化查询条件,更好使用我们已知的SQL技巧。

   当我们不是大神的时候,我们在发现性能问题的时候,我们的分析方式可以是:你有没有犯常识性的SQL错误?你有没有选择合适的数据结构?你有没有思考过业务模型非常糟糕?
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

性能优化之数据库操作异步化

最近在做一个系统优化的项目,经排查发现程序存在大量的数据库操作,且是同步的,导致性能急剧下降。因相关数据库操作对实时性要求不是很强,所以打算部署一个数据库操作进程模块,负责系统所有异步的数据库操作请求...

Linux系统中MySQL数据库操作命令

【注:可以在mysql中通过mysql> SELECTVERSION();来查看数据库版本】 一、连接MYSQL。 格式: mysql -h主机地址 -u用户名 -p用户密码 1、连接到本机...

JSP+Servlet培训班作业管理系统[8] -数据库操作层实现

本篇实现数据库相关的实体类(entity包)和操作类(operation包),具体代码如下:/*entity包下的实体类,与数据库中的表是对应关系*/ package entity; public c...

机房收费系统 重构(5)——数据库操作(存储过程)

背景:

如何在centOS等一些linux系统下安装oracle sqldeveloper图形化数据库操作界面

在这之前,请先参考我的这篇文章,即先按照

系统中数据库操作封装

封装数据的链接 package com.cloud.day2; import org.springframework.jdbc.core.JdbcTemplate; import...
  • dzy21
  • dzy21
  • 2016年07月25日 14:14
  • 1628

绩效考核系统开发心得之三__数据库操作

前言: 数据库操作是这次开发的一个让我头疼的点,因为老师最初设计的数据库是Access..而网页又要用php来写,这让我郁闷许久,因为我什么都不会...连php都是现学的。网络上查到关于php操作数据...

Linux系统命令及MYSQL数据库操作命令的备忘录

本文主要记录作者在Linux系统开发上常用的一些命令,对其做一个备忘记录。...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据库操作中是什么在影响系统的性能
举报原因:
原因补充:

(最多只允许输入30个字)