mysql优化心得

本文主要通过数据库表设计、sql处理、应用层优化三个层面,来谈谈笔者在工作中的一些心得和建议。

合理设计数据库表

合理添加索引

(1)经常进行条件查询(where或join on)的字段考虑加上索引

(2)经常分组(GROUP BY)或排序(ORDER BY)的字段考虑加上索引(Btree)

(3)差异性大的字段才适合建立索引

差异性表示某行数据的字段在所有数据中是否足够独特,鹤立鸡群。就好像qq号,独一无二,全部数据中的qq号都不一样;相对而言,性别男或者女,都有近一半是相同的,这时候加上索引效果并不理想。

有一种情况,例如某个文章的状态status(0未审核,1审核通过待发布,2已发布,3审核不通过),我们应用层有个定时器(10秒一次)在扫数据库中 审核通过待发布的,然后进行发布,更新status为2。在实际数据中,尽管大部分数据都是已发布(差异性小),但审核通过待发布的数据是非常少的(差异性较大),这时候也可以考虑加上索引(用于where status=1的条件查询则非常有效)。

(4)当需要保证数据某个重要字段的唯一性时,考虑加上唯一索引(做数据库级别的限制往往能避免很多因为错误数据导致的问题)

注:索引并不是越多越好,因为增加索引后,新增(insert)或更新对应字段(update)时,索引会做对应的调整,效率会有一定影响,索引越多影响越大。

表字段个数不要太多

我们公司是建议业务相关字段10个以内。

一般最初设计阶段,某个业务表有很多字段时,可以考虑拆分。一是按业务逻辑分、二是根据预估使用频率分。

避免使用触发器、函数、存储过程等

函数、触发器这些往往在应用层就能处理,而开发人员可以直接管理,并不需要和DBA打过多的交道,移植也方便。

另外数据库是拿来存数据的,除了增删改查,其他都不建议让数据库层面来干了。

注意 varchar 长度,取合理长度即可

varchar 超过255会多1个字节存储该字段值的长度;比如varchar(255)使用1个字节存储值长度,而varchar(256)则需要2个。

而定义的长度会影响对应的索引长度,比如 varchar(100) 和 varchar(20) 其对应建立的索引,前者要比后者的长度要大。

所以在满足业务场景的前提下,尽量取小的值即可。

小数(点)的设计,考虑使用decimal

在业务中往往包含一些小数的设计,例如价格(9.99元)、重量(51.3kg)等。

因为float和double这种浮点类型都存在精度问题,当需要较高精度时,可以使用decimal来取代;

另外一种达到要求精度的方案是降低字段表示的单位,从而消除小数,例如9.99元=999分,51.3kg=51300g,对应的字段使用整数表示即可。这种设计可能会增加应用层的复杂度(需要单位转换等),但如果经常进行排序的话,会有一定优势。

而在一些金融相关的行业,有时候往往不仅仅精确小数点后面两三位,而是4位、5位甚至更多位(例如0.9065元),这时候最好使用decimal。

注:decimal(10,4) 中,4表示小数位数,插入时超出则进行截取;10表示含小数在内的最多位数,这里整数则最多 (10-4) 位,超出时则报错。

sql篇

尽量避免联表查询

  • 联表查询时,数量尽量不要超过2个
  • 使用单表某些数据缓存(redis、memcached等)+ 应用层代码实现联表查询
  • 必要时,联表查询的条件列加上索引

大量数据时需要分页时 用索引字段条件查询 + limit N 替代直接 limit M,N

在大量数据时,mysql的limit M,N分页是存在比较严重的性能问题的,因为其会扫足前面M+N条数据,然后再取N条;当M非常大时,如2000万+时,效率就会非常慢了(10s+);

其中一个解决方法是:适当结合索引字段(如主键id)+ limit N 就能避免这个问题。

如 :select id, userName from t_user limit 20 000 000, 50;

假设第2000万条数据的id为 22 000 000;

改为:select id, userName from t_user where id >= 22 000 000 limit 50;

尽管在实际中客户端往往没有这样需求(页码太大),但当需要加载所有数据时则经常用到(如缓存预热)。

不要对条件查询的字段进行运算或函数操作

反例

(1) select id from t_user where age/2 > 10;

(2) select id from t_user where year(birthday) < 2000;

当age或birthday存在索引时,上面的语句并不会使用索引,而是直接进行全表扫描。

修改为

(1) select id from t_user where age > 20;

(2) select id from t_user where birthday < ‘2000-01-01’;

上面的转换均可以在应用层的代码实现,尽量不要在数据库层面进行运算操作。

经典优化

  • name字段有索引,name like ‘%zhang%’ 没有用上索引,而name like ‘zhang%’则用上。
  • 联合索引(name, age) 最左匹配,where name=’li’ 或 where name=’li’ and age=18 用上该索引,而where age=18 则无法用到该索引。
  • 连接查询一般 优于 子查询
  • exist 优于 in
  • 范围查询 between and 优于 in
  • insert into t values(..),(..); 优于多条 insert into t (…);,因为前者索引只做了一次调整。

应用层优化

能在应用层处理的就不要在数据库处理

数据库连接数量时有限的,数据库处理的东西越少,压力越小,处理时间越短,连接放回连接池的速度就越快,整个应用的吞吐量也会随之增大。

所以一些条件运算、函数计算等都可以尽量在应用层面进行。

注:要综合考虑代价,不要什么都不管就往应用层里面怼。当运用到索引的分组、排序往往在数据库中处理效率更高。

合理利用缓存

一些热点数据可以进行缓存,这时候大流量下,可以大大减少DB的压力。

利用消息机制进行异步DB操作

高并发下,DB往往扛不住,要么直接被压垮,要么连接数远远不够用。

目前来说,利用消息机制进行异步处理(相关DB操作)是一个不错的选择,因为消费的线程数量是有限的(DB可以承受的范围),这时候DB不会有那么大的压力,可以保证整个应用和DB都正常运行。

当结合缓存时,就能保证异步处理期间,仍认为数据已经被正常处理的了,因为取数据时,优先取缓存中的而不是DB。

选择适合的框架

为了简化开发往往会选择对DB操作的框架,而这个的选择在数流量/数据量小时往往没有什么区别。但是一旦到哪里都在抠性能时,这里的优化往往是非常重要的。

一个是考虑公司情况(对哪种框架处理更有经验),另外一个是考虑业务场景,不同的框架往往有其擅长的地方。

如果选择不合适(可能框架本身原因,肯能是因为对框架缺乏了解),想要优化时,往往显得捉襟见肘,难以应对。

总结

  1. 数据库是拿来存东西的,擅长的是增删改查,而不是各种逻辑处理和计算
  2. 结合实际业务场景,才能设计出最合理的字段,不长不短,不多不少
  3. sql优化归根结底都是怎样把索引给用上,把索引的作用最大化
  4. 善用缓存

原文链接 大专栏  https://www.dazhuanlan.com/2019/08/17/5d5774337b04d/

原文地址:https://www.cnblogs.com/chinatrump/p/11417377.html

时间: 2024-10-08 00:21:28

mysql优化心得的相关文章

我的MYSQL学习心得(十六) 优化

这一篇主要介绍MYSQL的优化,优化MYSQL数据库是DBA和开发人员的必备技能 MYSQL优化一方面是找出系统瓶颈,提高MYSQL数据库整体性能:另一方面需要合理的结构设计和参数调整,以提高 用户操作响应的速度:同时还有尽可能节省系统资源,以便系统可以提供更大负荷的服务 如果大家看过我写的两篇文章,那么学习MYSQL的索引就不会太难,因为是相通的 SQLSERVER聚集索引与非聚集索引的再次研究(上) SQLSERVER聚集索引与非聚集索引的再次研究(下) 其实MYSQL也有SQLSERVER

我的MYSQL学习心得(十) 自定义存储过程和函数

我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(八) 插入 更新 删除 我的MYSQL学习心得(九) 索引 我的MYSQL学习心得(十一) 视图 我的MYSQL学习心得(十二) 触发器 我的MYSQL学习心得(十三) 权限管理 我的MYSQL学习

第24章 mysql 优化

2015-10-25 目录 参考资料 [1] 唐汉明.深入浅出MySQL 数据库开发.优化与管理维护(第2版)[M].北京:人民邮电出版社,2014 [2] Schwartz.高性能MySQL(第3版)[M].北京:电子工业出版社,2013 [3] MySQL 性能优化的最佳20多条经验分享 [4] mysql性能优化-慢查询分析.优化索引和配置 [5] MySQL优化必须调整的10项配置 [6] MySQL 配置优化 [7] Mysql数据库优化总结 [8] MySQL安装配置与性能优化 [9

我的MYSQL学习心得(十五)

我的MYSQL学习心得(十五) 我的MYSQL学习心得(一) 我的MYSQL学习心得(二) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) 我的MYSQL学习心得(五) 我的MYSQL学习心得(六) 我的MYSQL学习心得(七) 我的MYSQL学习心得(八) 我的MYSQL学习心得(九) 我的MYSQL学习心得(十) 我的MYSQL学习心得(十一) 我的MYSQL学习心得(十二) 我的MYSQL学习心得(十三) 我的MYSQL学习心得(十四) 这一篇<我的MYSQL学习心得(十五)>

我的MYSQL学习心得

我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(八) 插入 更新 删除 我的MYSQL学习心得(九) 索引 我的MYSQL学习心得(十) 自定义存储过程和函数 我的MYSQL学习心得(十一) 视图 我的MYSQL学习心得(十二) 触发器 我的MY

我的MYSQL学习心得(十六)

我的MYSQL学习心得(十六) 我的MYSQL学习心得(一) 我的MYSQL学习心得(二) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) 我的MYSQL学习心得(五) 我的MYSQL学习心得(六) 我的MYSQL学习心得(七) 我的MYSQL学习心得(八) 我的MYSQL学习心得(九) 我的MYSQL学习心得(十) 我的MYSQL学习心得(十一) 我的MYSQL学习心得(十二) 我的MYSQL学习心得(十三) 我的MYSQL学习心得(十四) 我的MYSQL学习心得(十五) 一步一步

MYSQL学习心得

转载:http://www.cnblogs.com/lyhabc/p/3691555.html 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(八) 插入 更新 删除 我的MYSQL学习心得(九) 索引 我的MYSQL学习心得(十) 自定义存储过

我的MYSQL学习心得(十五) 日志

原文:我的MYSQL学习心得(十五) 日志 我的MYSQL学习心得(十五) 日志 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(八) 插入 更新 删除 我的MYSQL学习心得(九) 索引 我的MYSQL学习心得(十) 自定义存储过程和函数 我的

我的MYSQL学习心得(十四) 备份和恢复

原文:我的MYSQL学习心得(十四) 备份和恢复 我的MYSQL学习心得(十四) 备份和恢复 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(八) 插入 更新 删除 我的MYSQL学习心得(九) 索引 我的MYSQL学习心得(十) 自定义存储过程