当我们优化一个系统时,有时发现一种情况就是自己修改SQL,索引以及分区是不能解决性能问题的。这时你要考虑业务逻辑优化和表设计的重构。这两点的确和设计结合的很紧密。
结合实际,我们先谈谈业务逻辑优化。
案例一:
我们的系统一个文档模块,客户点击时很慢,通过性能分析,是点击是去查询数据库,这时系统是通过Hibernate来两步处理:
1,计算该类型的文档数量总数。
2,显示最新文档的前20篇文档。
这时显示第二步的时间是很快的,只取20条记录,但是计算该类型的所有总数很慢。系统的这时的输入是很大的(计算该类型的全部文档,可能有几万篇数据),输出就一条总数。这时因为业务逻辑复杂,即使建立索引,分区等等速度也是无法提高,因为不能真正做到索引覆盖和分区消除。
客户是点一下要等十几秒是不能容忍的,这时可能输入数据量很大下,数据库很可能采用的是hash联结,而且并发用户一大,数据库服务器压力很大。
这时常规的优化方法是没有效果的。这时我们也发现,客户其实对以前比较老的数据是不关心的,一般只是对近期的数据比较感兴趣,所有我们就在查询时默认设定半年的时间,然后在时间上设定聚集索引。并默认在此时间上排序,使其使用合并联结,减少输入数据量,结果速度有明显的提升。
案例二:
我们在优化一个客户系统时,碰到一种情况,在客户的一选择功能时,客户点击一下选择相关数据,这时页面要要几分钟才能出来,客户很不满意,这时修改sql和索引都没有办法,他的输入的数据量也很大,和上面一下也要计算总数和取最新前几条数据。
这时我们在查询是关联了人员,通过调查,发现客户只对和自己相关的数据感兴趣。也只是查询自己相关的数据。所以这时在sql语句里增加用户id这条限制,同时在增加userid的索引,这样一来,速度就大大提高。
当然以上两个案例,是从输入入手,减少输入和输出的数据量,主要优化业务逻辑,达到优化系统。当然有些情况要和客户确认和说服他们,有时他们不一定都认可,这时要说明这样做的目的,相信他们也会理解。
表设计,在我们开发系统时已经确定,好的设计的确能大大提高性能,我们在优化系统时,碰到一个比较麻烦的问题。
以前讨论的原文地址: 数据库重构(一):字段合并
这条sql是判断5个维度,一个用户id, 一个机构id,一个岗位id, 还有级别判断和是否公共。sql语句里有5个”or“组成查询,表数据一大就表扫描,性能很差,但业务要求和系统要求这样判断。即使在表中这五个字段都建索引,速度也不会快。太多"OR"了,SQL Server 查询分析器无法优化。
这时由于设计时: 用户id,机构id,岗位id为3个只有一个有数据。所以将这3个字段合并,较少"Or"语句,让数据库能使用索引。
表设计是优化是让sql语句能使用到索引,或者增加冗余字段减少其输入和输出数据,或者减少查询数据(如计算静态表),典型的如索引视图,数据仓库等。