加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码门户网 (https://www.92codes.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 搜索优化 > 正文

MySql相关优化分享

发布时间:2022-12-16 14:07:51 所属栏目:搜索优化 来源:未知
导读: 文章目录
前言
现在在网上搜索,有很多类似文章,mysql优化大全mysql 模糊搜索 优化,mysql最强总结等等,部分文章存在一些错误。在这里个人总结整理的一些点,希望对大家有所帮助。
本篇从

文章目录

前言

现在在网上搜索,有很多类似文章,mysql优化大全mysql 模糊搜索 优化,mysql最强总结等等,部分文章存在一些错误。在这里个人总结整理的一些点,希望对大家有所帮助。

本篇从数据库、表、sql语句几个维度来说优化,如果文章有误之处欢迎指正~

一、数据库优化 1.选择合适存储引擎

MySQL5.5版本开始,InnoDB已经成为Mysql的默认引擎(之前是MyISAM),说明其优势是有目共睹的。如果你不知道用什么存储引擎,那就用InnoDB,至少不会差。

如何选择呢:

是否要支持事务,如果要请选择 InnoDB,如果不需要可以考虑 MyISAM;如果表中绝大多数都只是读查询,可以考虑 MyISAM,如果既有读,写也挺频繁,请使用InnoDB。系统奔溃后,MyISAM恢复起来更困难,能否接受,不能接受就选 InnoDB; 2.选择合适的连接池

1:性能方面 hikariCP>druid>tomcat-jdbc>dbcp>c3p0 。hikariCP的高性能得益于最大限度的避免锁竞争。

2:druid功能最为全面,sql拦截等功能,统计数据较为全面,具有良好的扩展性。

3:HikariCP因为细节方面优化力度较大,性能方面强于Druid

4:综合性能,扩展性等方面,可考虑使用druid或者hikariCP连接池。

注:SpringBoot 2.0以后默认连接池是hikariCP。

3.分库分表

在数据量增长和增长速度越来越高的情况下,单库可能在容量、IO、并发性能上都无法支撑,这个时候就要对业务进行切分或数据库进行扩展,数据库的扩展也就是分库分表。

分库分表的方式有垂直拆分和水平拆分。

垂直拆分是根据业务进行拆分,这种拆分不能解决单业务点数据量大的问题。

水平拆分是根据某一列进行拆分(如id,userId),拆分后的每个库结构一致。

4.主从同步

一般部署架构为一台 Master 和 n 台 Slave,Master 的主责为写,并将数据同步至 Slave,Slave 主要提供查询功能。

可以使用数据库中间件,例如MyCat来实现。MyCat的读写分离是建立在MySQL主从复制基础之上实现的,Mycat读写分离和自动切换机制,需要mysql的主从复制机制配合。

二、表优化 1.表中的字段选择合适的数据类型

1、当一个列可以选择多种数据类型时,应该优先考虑数字类型,其次是日期和二进制类型,最后是字符类型。

2、对于相同级别的数据类型,应该优先选择占用空间小的数据类型。

2.适当添加索引 3.表中适当保留冗余数据

具体做法是: 在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,减少了查询时的关联,提高查询效率。

4.增加中间表

对于需要经常联合查询的表,可以建立中间表以提高查询效率。通过建立中间表,把需要经常联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询,以此来提高查询效率。

5.字段很多的表分解成多个表

对于字段比较多的表,如果有些字段的使用频率很低,可以将这些字段分离出来形成新表。因为当一个表的数据量很大时,会由于使用频率低的字段的存在而变慢。

6.添加适当存储过程

一个存储过程是一个可编程的函数,它在数据库中创建并保存,一般由 SQL语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的特定功能时,存储过程尤为合适。

存储过程与SQL语句如何抉择:

架构设计没有绝对,只有在当前的场景下最合适的。

普通的项目开发中,不建议大量使用存储过程,对比SQL语句,存储过程适用于业务逻辑复杂,比较耗时,同时请求量较少的操作,例如后台大批量查询、定期更新等。

(1)当一个事务涉及到多个SQL语句时或者涉及到对多个表的操作时可以考虑应用存储过程

(2)在一个事务的完成需要很复杂的商业逻辑时可以考虑应用存储过程

(3)比较复杂的统计和汇总可以考虑应用后台存储过程

三、SQL语句优化 1.尽量使用表的别名,减少解析

当在SQL语句中连接多个表时, 使用表的别名并把别名前缀于每个Column上,这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误。

2.select子句中避免使用*号 3.将where中用的比较频繁的字段建立索引,避免全表扫描

1.普通索引:这是最基本的索引类型,而且它没有唯一性之类的限制。

2.唯一索引:和普通索引基本相同,只是索引列的所有值都只能出现一次,即必须唯一。

3.主键索引:就是 唯一 且 不能为空。主键索引是一种特殊的唯一索引。必须指定为“PRIMARY KEY”。

4.联合索引:多列值组成一个索引,专门用于组合搜索。

5.全文索引:用于在一篇文章中,检索文本信息的,适合在进行模糊查询的时候使用。

提示点:

4.避免索引失效情况

索引失效情况

1、like查询以“%”开头;(这个范围非常大,所以没有使用索引的必要了)

2、or查询左右都没有使用索引;(or可以使用unint)

3、联合索引中没有使用第一列索引;(为遵循最左匹配原则)

4、在where中索引列上使用“not”,“”,“!=”;(不等于操作符可能不会用到索引的,产生全表扫描)

5、在where中索引列上使用函数或进行计算操作,索引失效。(更改字段导致失效)

6、如果mysql觉得全表扫描更快时(数据少时)

7、在索引列上使用“IS NULL”或“IS NOT NULL”操作,索引可能失效(如果列上全部数据不为空,索引会失效,但是如果有空值,索引不会失效)

在这里插入图片描述

5.当只需要一条数据的时候可以使用limit 1

这是为了使EXPLAIN中type列达到const类型

6.调整Where字句中的连接顺序

采用自下而上的顺序解析where字句,根据这个原理表连接最好写在其他where条件之前,那些可以过滤掉最大数量记录。

7.小表驱动大表

SQL中使用in:

如果sql语句中包含了in关键字,则它会优先执行in里面的子查询语句,然后再执行in外面的语句。所以假如in里面的数据量很少,作为条件查询速度更快。

SQL中使用exists:

如果sql语句中包含了exists关键字,它会优先执行exists左边的语句(即主查询语句)。然后把它作为条件,去跟右边的语句匹配。

如果匹配上,则可以查询出数据。如果匹配不上,数据就被过滤掉了。

这个需求中,如果order表有10000条数据,而user表有100条数据。order表是大表,user表是小表。如果order表在左边,则用in关键字性能更好。

总结一下:

in 适用于左边大表,右边小表。

exists 适用于左边小表,右边大表。

8.善用 EXPLAIN 查看SQL执行计划

EXPLAIN select  column_name from table_name;

在这里插入图片描述

type列,访问类型。一个好的sql语句至少要达到range(范围)级别。杜绝出现all级别。

ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)key列,使用到的索引名。如果没有选择索引,值是NULL。可以采取强制索引方式。key_len列,索引长度。rows列,扫描行数。该值是个预估值 。extra列,详细说明。注意常见的不太友好的值有:Using filesort, Using temporary。

具体的优化步骤:

1、首先要避免全表扫描,检查是否有索引。

2、查看索引是否生效。

3、sql结构的优化。

4、数据库表设计的优化。

(编辑:源码门户网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!