详解如何做好数据库的优化 (如何做好?)

教程大全 2025-07-19 20:32:12 浏览

为了让 数据库 更好的为人民服务,当前至关重要的就是 数据库优化 ,只有优化了数据库,使其性能提升,运用数据库时才能方便快捷。目前web2.0的程序,很大瓶颈是数据库的吞度量。不过,如何才能确定系统的瓶颈是数据库呢,因为只有确定数据库是整个系统的瓶颈,我们才有必要去优化他,毕竟,还有这么多需求等待我们去做。

如何确定数据库是瓶颈?

1 如果程序设计良好,有一个数据库操作逻辑层,可以从这个层的统计数据看到每个请求花费的时间,如果平均时间已经不能让你容忍的话,数据库已经是瓶颈了。

详解如何做好的优化

2 在数据库的 服务器 上使用top命令,看看mysql服务器占用资源的情况,看看机子的平均负载。

如果服务器的平均负载已经很高,mysql占用了块100%的cpu资源,说明mysql服务器很忙了。

3 在数据库服务器上使用iostat命令,看看磁盘IO,如果block住的操作比较多的话,说明数据库操作还是过于频繁了,磁盘都响应不急了。

4 建议打开mysql的慢查询日志,这样grep select看一下日志中的慢查询的数量,如果数量较多,说明慢查询的数量很多,需要进行调整了。

5 如果有一天数据库无法插入了,需要检查一下数据库表是不是过大了。32位的操作系统上一个表最大的容量是2^32这么大。不过还是建议增加一个数据库操作的逻辑层,在数据库操作的前后记录下操作的时间,进行统计上报,利用监控程序来报警相关负责人,这样可以及早的知道数据库是瓶颈,提前做出优化。

知道数据库是瓶颈了,如何来进行优化呢?

1 我们第一个想到是看看数据库的容量是不是太大了,如果数据库表太大的话,索引文件也会比较大,每次的更新操作就会更加的费时。需要考虑进行分库和分表了。

分库分表按照一定的规则来对数据库中的记录进行分区来存储,一方面可以做到一定的负载均衡,将请求平分下来,每个区段去独自承受;另一方面,分库分表可以使我们存储和操作更多的数据。

不过分库分表需要多之前基于单库的程序进行修改,存在一定的风险,因此,在程序设计之初就应该考虑到分库分表的需要,最好是将数据库操作层独立出来,便于扩展和更改。

2 如果数据库表不是很大,但是查询慢的话,我们需要检查一下我们的sql查询语句,利用mysql的explain语句看看是不是使用了索引,如果没有使用索引,那我们需要在相应的字段上建上索引,反复的使用explain,寻找到个一个合适的索引。

在建索引时需要考虑:

1)数据库的索引要做到越少越好:因为每次更新都需要更新索引,索引过多就会降低写入的速度

2)最窄的字段放在键的左边:这样提高了索引中每一个点的基数,带来更好的索引读写性能

3)尽量避免file sort排序、临时表和表扫描:对于大表,全表扫描会导致大量的磁盘IO的操作,会导致操作非常的缓慢

4)对于大表,尽量不要将索引建在字符串类型的列上,字符串的匹配是很费时的,需要付出很高的性能代价,如果一定有必要,建议对字符串列进行hash后取一个整形的值来进行索引。

3 如果更新操作有点慢,而读操作的响应要求不需要很及时的话,可以考虑利用mysql的主从热备来分担读写的压力。

毕竟对数据库的操作,写少读多。因此,我们将对数据库的写操作放到mysql的主服务器上,利用mysql的热备,我们在备份的数据库服务器上进行读操作,由于可以有多个热备mysql,于是可以将读操作分布在多个热备上面,从而将读操作均衡开来,提高读操作的性能。

4 缓存的使用

缓存是一切后台程序的根本,因为80%的请求是对应20%的数据,我们只需要少量的内存将20%的数据缓存起来,就可以大大的满足我们系统需求,何乐而不为呢。

1)mysql设置中尽量增加key cache,thread cache、查询的cache

2)在应用程序层增加一个memcached这样的通用cache

3)对于少量数据,但是操作频繁的表使用mysql提供的内存heap表,可以获得极高的写入和读取速度

5 数据库的设计上进行优化

对于传统的数据库设计我们讲究建模范式,避免数据的冗余从而导致脏数据。然而在我们实际的应用中需要根据情况来使用第三范式的一些规则,对于一些频繁需要在多个地方出现的数据,如同一个论坛这种用户和主题以及回复等有关联的应用中,如果我们将用户同主题和回复分开来存储,每次查询一下一篇文章或者一个回复的情况都需要对用户表和主题表或者回复表进行联查,如果数据量小的话,这样联查的性能还是可以接受的,如果表大一点,上了3、4十万以上的数据,联查的速度就会比较慢了。

该范式化的地方需要进行范式化,但是还是需要根据情况来设计我们的表,从而达到性能和良好设计的折中。

其它的话:

1 对于数据库的操作建议分层处理,至少分为两层,一层是数据库操作的逻辑层,一层是数据库的cache层。

从一开始就考虑如此,可以很方便在未来对数据库进行划分部署、分库分表扩展

2 增加mysql的监控,监控mysql的慢查询日志,监控mysql的请求情况

3 根据自己的需要来选择mysql的存储引擎

myisam有较高的读写速度,但是由于表锁定,不能同时进行快速的读和写。

innodb支持事务,提供了行级的锁,但是为了使用事务,表空间会比较大,而且不支持全文索引

heap将表放到内存中,适合与表小而需要频繁操作的情况,如用户信息,其读写很快,但是不是持久的,需要自己来写工具让其持久

4 mysql服务器的一些状态检测的命令

show slave status:可以看到主从同步的情况

show [full] processlist:可以看到mysql服务器的请求情况,如果发现lock情况很多,需要注意了

show status:可以看到mysql服务器的各种请求情况。

以上主要讲解了 确定数据库是瓶颈、如何来进行优化 两大问题,通过上面的学习,相信数据库优化问题已经难不倒您啦。

【编辑推荐】


如何正确的使用MongoDB并优化其性能

e799bee5baa6e79fa5ee4b893e5b19e136数据库性能对软件整体性能的影响是不言而喻的,那么,当我们使用MongoDB时改如何提高数据库性能呢?1.范式化与反范式化在项目设计阶段,明确集合的用途是对性能调优非常重要的一步。 从性能优化的角度来看,集合的设计我们需要考虑的是集合中数据的常用操作,例如我们需要设计一个日志(log)集合,日志的查看频率不高,但写入频率却很高,那么我们就可以得到这个集合中常用的操作是更新(增删改)。 如果我们要保存的是城市列表呢?显而易见,这个集合是一个查看频率很高,但写入频率很低的集合,那么常用的操作就是查询。 对于频繁更新和频繁查询的集合,我们最需要关注的重点是他们的范式化程度,在上篇范式化与反范式化的介绍中我们了解到,范式化与反范式化的合理运用对于性能的提高至关重要。 然而这种设计的使用非常灵活,假设现在我们需要存储一篇图书及其作者,在MongoDB中的关联就可以体现为以下几种形式:1.完全分离(范式化设计)示例1:View Code{ _id : ObjectId(5124b5dc7dca), title : 如何使用MongoDB, author : [ ObjectId(144b5dc7dca),ObjectId(144b5dc7dca),ObjectId(144b5dc7dca), ] }我们将作者(comment) 的id数组作为一个字段添加到了图书中去。 这样的设计方式是在非关系型数据库中常用的,也就是我们所说的范式化设计。 在MongoDB中我们将与主键没有直接关系的图书单独提取到另一个集合,用存储主键的方式进行关联查询。 当我们要查询文章和评论时需要先查询到所需的文章,再从文章中获取评论id,最后用获得的完整的文章及其评论。 在这种情况下查询性能显然是不理想的。 但当某位作者的信息需要修改时,范式化的维护优势就凸显出来了,我们无需考虑此作者关联的图书,直接进行修改此作者的字段即可。 2.完全内嵌(反范式化设计)示例2:View Code{ _id : ObjectId(5124b5dc7dca), title : 如何使用MongoDB, author : [{ name : 丁磊 age : 40, nationality : china,},{ name : 马云 age : 49, nationality : china,},{ name : 张召忠 age : 59, nationality : china,},]} 在这个示例中我们将作者的字段完全嵌入到了图书中去,在查询的时候直接查询图书即可获得所对应作者的全部信息,但因一个作者可能有多本著作,当修改某位作者的信息时时,我们需要遍历所有图书以找到该作者,将其修改。 3.部分内嵌(折中方案)示例3:View Code{ _id : ObjectId(5124b5dc7dca), title : 如何使用MongoDB, author : [ { _id : ObjectId(144b5dc7dca), name : 丁磊},{ _id : ObjectId(144b5dc7dca), name : 马云},{ _id : ObjectId(144b5dc7dca), name : 张召忠},]}这次我们将作者字段中的最常用的一部分提取出来。 当我们只需要获得图书和作者名时,无需再次进入作者集合进行查询,仅在图书集合查询即可获得。 这种方式是一种相对折中的方式,既保证了查询效率,也保证的更新效率。 但这样的方式显然要比前两种较难以掌握,难点在于需要与实际业务进行结合来寻找合适的提取字段。 如同示例3所述,名字显然不是一个经常修改的字段,这样的字段如果提取出来是没问题的,但如果提取出来的字段是一个经常修改的字段(比如age)的话,我们依旧在更新这个字段时需要大范围的寻找并依此进行更新。 在上面三个示例中,第一个示例的更新效率是最高的,但查询效率是最低的,而第二个示例的查询效率最高,但更新效率最低。 所以在实际的工作中我们需要根据自己实际的需要来设计表中的字段,以获得最高的效率。

提高mysql查询效率的方法有哪些

1.尽量不要在where中包含子查询;关于时间的查询,尽量不要写成:where to_char(dif_date,’yyyy-mm-dd’)=to_char(‘2007-07-01′,’yyyy-mm-dd’);2.在过滤条件中,可以过滤掉最大数量记录的条件必须放在where子句的末尾;FROM子句中写在最后的表(基础表,driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。 如果有三个以上的连接查询,那就需要选择交叉表 (intersection table)作为基础表,交叉表是指那个被其他表所引用的表;3.采用绑定变量4.在WHERE中尽量不要使用OR5.用EXISTS替代IN、用NOT EXISTS替代NOT IN;6.避免在索引列上使用计算:WHERE SAL*12>;7.用IN来替代OR: WHERE LOC_ID=10 OR LOC_ID=15 OR LOC_ID=208.避免在索引列上使用IS NULL和IS NOT NULL;9.总是使用索引的第一个列;10.用UNION-ALL替代UNION;11.避免改变索引列的类型:SELECT…FROM EMP WHERE EMPNO=’123’,由于隐式数据类型转换,to_char(EMPNO)=’123’,因此,将不采用索引,一般在采用字符串拼凑动态SQL语句出现;12.’!=’ 将不使用索引;13.优化GROUP BY;14.避免带有LIKE参数的通配符,LIKE ‘4YE%’使用索引,但LIKE ‘%YE’不使用索引15.避免使用困难的正规表达式,例如select * from customer where zipcode like “98___”,即便在zipcode上建立了索引,在这种情况下也还是采用顺序扫描的方式。 如果把语句改成select * from customer where zipcode>”″,在执行查询时就会利用索引来查询,显然会大大提高速度;16.尽量明确的完成SQL语句,尽量少让数据库工作。 比如写SELECT语句时,需要把查询的字段明确指出表名。 尽量不要使用SELECT *语句。 组织SQL语句的时候,尽量按照数据库的习惯进行组织。

mysql查询优化,1万条数据居然要30秒

索引创建规则:1、表的主键、外键必须有索引;2、数据量超过300的表应该有索引;3、经常与其他表进行连接的表,在连接字段上应该建立索引;4、经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;5、索引应该建在选择性高的字段上;6、索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引;7、复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:A、正确选择复合索引中的主列字段,一般是选择性较好的字段;B、复合索引的几个字段是否经常同时以AND方式出现在Where子句中?单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引;C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;D、如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;8、频繁进行数据操作的表,不要建立太多的索引;9、删除无用的索引,避免对执行计划造成负面影响;以上是一些普遍的建立索引时的判断依据。 一言以蔽之,索引的建立必须慎重,对每个索引的必要性都应该经过仔细分析,要有建立的依据。 因为太多的索引与不充分、不正确的索引对性能都毫无益处:在表上建立的每个索引都会增加存储开销,索引对于插入、删除、更新操作也会增加处理上的开销。 另外,过多的复合索引,在有单字段索引的情况下,一般都是没有存在价值的;相反,还会降低数据增加删除时的性能,特别是对频繁更新的表来说,负面影响更大。

本文版权声明本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请联系本站客服,一经查实,本站将立刻删除。

发表评论

热门推荐