关于mysql的项目_项目中常用的MySQL 优化
本文我们来谈谈项目中常用的MySQL优化方法,共19条,具体如下:
一、EXPLAIN
做MySQL优化,我们要善用EXPLAIN查看SQL执行计划。
下面来个简单的示例,标注(1、2、3、4、5)我们要重点关注的数据:
type列,连接类型。一个好的SQL语句至少要达到range级别。杜绝出现all级别。
key列,使用到的索引名。如果没有选择索引,值是NULL。可以采取强制索引方式
key_len列,索引长度。
rows列,扫描行数。该值是个预估值。
extra列,详细说明。注意,常见的不太友好的值,如下:Using filesort,Using temporary。
二、SQL 语句中 IN 包含的值不应过多
MySQL对于IN做了相应的优化,即将IN中的常量全部存储在一个数组里面,而且这个数组是排好序的。但是如果数值较多,产生的消耗也是比较大的。再例如:select id from t where num in(1,2,3) 对于连续的数值,能用between就不要用in了;再或者使用连接来替换。
三、SELECT语句务必指明字段名称
SELECT*增加很多不必要的消耗(CPU、IO、内存、网络带宽);增加了使用覆盖索引的可能性;当表结构发生改变时,前断也需要更新。所以要求直接在select后面接上字段名。
四、当只需要一条数据的时候,使用limit 1
这是为了使EXPLAIN中type列达到const类型
五、如果排序字段没有用到索引,就尽量少排序
六、如果限制条件中其他字段没有索引,尽量少用or
or两边的字段中,如果有一个不是索引字段,而其他条件也不是索引字段,会造成该查询不走索引的情况。很多时候使用union all或者是union(必要的时候)的方式来代替“or”会得到更好的效果。
七、尽量用 union all 代替 union
union和union all的差异主要是前者需要将结果集合并后再进行唯一性过滤操作,这就会涉及到排序,增加大量的CPU运算,加大资源消耗及延迟。当然,union all的前提条件是两个结果集没有重复数据。
八、不使用ORDER BY RAND()
select id from `dynamic` order by rand() limit 1000;
上面的SQL语句,可优化为:
select id from `dynamic` t1 join (select rand() * (select max(id) from `dynamic`) as nid) t2 on t1.id > t2.nidlimit 1000;
九、区分in和exists、not in和not exists
select * from 表A where id in (select id from 表B)
上面SQL语句相当于
select * from 表A where exists(select * from 表B where 表B.id=表A.id)
区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询。所以IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
关于not in和not exists,推荐使用not exists,不仅仅是效率问题,not in可能存在逻辑问题。如何高效的写出一个替代not exists的SQL语句?
原SQL语句:
select colname … from A表 where a.id not in (select b.id from B表)
高效的SQL语句:
select colname … from A表 Left join B表 on where a.id = b.id where b.id is null
取出的结果集如下图表示,A表不在B表中的数据:
十、使用合理的分页方式以提高分页的效率
select id,name from product limit 866613, 20
使用上述SQL语句做分页的时候,可能有人会发现,随着表数据量的增加,直接使用limit分页查询会越来越慢。
优化的方法如下:可以取前一页的最大行数的id,然后根据这个最大的id来限制下一页的起点。比如此列中,上一页最大的id是866612。SQL可以采用如下的写法:
select id,name from product where id> 866612 limit 20
十一、分段查询
在一些用户选择页面中,可能一些用户选择的时间范围过大,造成查询缓慢。主要的原因是扫描行数过多。这个时候可以通过程序,分段进行查询,循环遍历,将结果合并处理进行展示。
如下图这个SQL语句,扫描的行数成百万级以上的时候就可以使用分段查询:
十二、避免在 where 子句中对字段进行 null 值判断
对于null的判断会导致引擎放弃使用索引而进行全表扫描。
十三、不建议使用%前缀模糊查询
例如LIKE“%name”或者LIKE“%name%”,这种查询会导致索引失效而进行全表扫描。但是可以使用LIKE “name%”。
那如何查询%name%?
如下图所示,虽然给secret字段添加了索引,但在explain结果并没有使用:
那么如何解决这个问题呢,答案:使用全文索引。
在我们查询中经常会用到select id,fnum,fdst from dynamic_201606 where user_name like '%zhangsan%'; 。这样的语句,普通索引是无法满足查询需求的。庆幸的是在MySQL中,有全文索引来帮助我们。
创建全文索引的SQL语法是:
ALTER TABLE `dynamic_201606` ADD FULLTEXT INDEX `idx_user_name` (`user_name`);
使用全文索引的SQL语句是:
select id,fnum,fdst from dynamic_201606 where match(user_name) against('zhangsan' in boolean mode);
注意:在需要创建全文索引之前,请联系DBA确定能否创建。同时需要注意的是查询语句的写法与普通索引的区别。
十四、避免在 where 子句中对字段进行表达式操作
比如:
select user_id,user_project from user_base where age*2=36;
中对字段就行了算术运算,这会造成引擎放弃使用索引,建议改成:
select user_id,user_project from user_base where age=36/2;
十五、避免隐式类型转换
where子句中出现column字段的类型和传入的参数类型不一致的时候发生的类型转换,建议先确定where中的参数类型。
十六、对于联合索引来说,要遵守最左前缀法则
举列来说索引含有字段id、name、school,可以直接用id字段,也可以id、name这样的顺序,但是name;school都无法使用这个索引。所以在创建联合索引的时候一定要注意索引字段顺序,常用的查询字段放在最前面。
十七、必要时可以使用force index来强制查询走某个索引
有的时候MySQL优化器采取它认为合适的索引来检索SQL语句,但是可能它所采用的索引并不是我们想要的。这时就可以采用forceindex来强制优化器使用我们制定的索引。
十八、注意范围查询语句
对于联合索引来说,如果存在范围查询,比如between、>、
LEFT JOIN A表为驱动表,INNER JOIN MySQL会自动找出那个数据少的表作用驱动表,RIGHT JOIN B表为驱动表。
注意:
1)MySQL中没有full join,可以用以下方式来解决:
select * from A left join B on B.name = A.namewhere B.name is nullunion allselect * from B;
2)尽量使用inner join,避免left join:
参与联合查询的表至少为2张表,一般都存在大小之分。如果连接方式是inner join,在没有其他过滤条件的情况下MySQL会自动选择小表作为驱动表,但是left join在驱动表的选择上遵循的是左边驱动右边的原则,即left join左边的表名为驱动表。
3)合理利用索引:
被驱动表的索引字段作为on的限制字段。
4)利用小表去驱动大表:
从原理图能够直观的看出如果能够减少驱动表的话,减少嵌套循环中的循环次数,以减少 IO总量及CPU运算的次数。
5)巧用STRAIGHT_JOIN:
inner join是由MySQL选择驱动表,但是有些特殊情况需要选择另个表作为驱动表,比如有group by、order by等「Using filesort」、「Using temporary」时。STRAIGHT_JOIN来强制连接顺序,在STRAIGHT_JOIN左边的表名就是驱动表,右边则是被驱动表。在使用STRAIGHT_JOIN有个前提条件是该查询是内连接,也就是inner join。其他链接不推荐使用STRAIGHT_JOIN,否则可能造成查询结果不准确。
这个方式有时能减少3倍的时间。
-----------------------------------------------------------------------------------
另外一篇文章关于mysql数据库优化的
前言
数据库优化一方面是找出系统的瓶颈,提高MySQL数据库的整体性能,而另一方面需要合理的结构设计和参数调整,以提高用户的相应速度,同时还要尽可能的节约系统资源,以便让系统提供更大的负荷.
1、优化一览图
2、优化
笔者将优化分为了两大类,软优化和硬优化,软优化一般是操作数据库即可,而硬优化则是操作服务器硬件及参数设置.
2.1 软优化
2.1.1 查询语句优化
1、首先我们可以用EXPLAIN或DESCRIBE(简写:DESC)命令分析一条查询语句的执行信息.
2.例:
DESC SELECT * FROM `user`
显示:
其中会显示索引和查询数据读取数据条数等信息.
2.1.2 优化子查询
在MySQL中,尽量使用JOIN来代替子查询.因为子查询需要嵌套查询,嵌套查询时会建立一张临时表,临时表的建立和删除都会有较大的系统开销,而连接查询不会创建临时表,因此效率比嵌套子查询高.
2.1.3 使用索引
索引是提高数据库查询速度最重要的方法之一,关于索引可以参高笔者一文,介绍比较详细,此处记录使用索引的三大注意事项:
1、LIKE关键字匹配'%'开头的字符串,不会使用索引.
2、OR关键字的两个字段必须都是用了索引,该查询才会使用索引.
3、使用多列索引必须满足最左匹配.
2.1.4 分解表
对于字段较多的表,如果某些字段使用频率较低,此时应当,将其分离出来从而形成新的表,
2.1.5 中间表
对于将大量连接查询的表可以创建中间表,从而减少在查询时造成的连接耗时.
2.1.6 增加冗余字段
类似于创建中间表,增加冗余也是为了减少连接查询.
2.1.7 分析表,检查表,优化表
分析表主要是分析表中关键字的分布,检查表主要是检查表中是否存在错误,优化表主要是消除删除或更新造成的表空间浪费.
1、分析表: 使用 ANALYZE 关键字,如ANALYZE TABLE user;
Op:表示执行的操作.
Msg_type:信息类型,有status,info,note,warning,error.
Msg_text:显示信息.
2、检查表: 使用 CHECK关键字,如CHECK TABLE user [option]
option 只对MyISAM有效,共五个参数值:
QUICK:不扫描行,不检查错误的连接.
FAST:只检查没有正确关闭的表.
CHANGED:只检查上次检查后被更改的表和没被正确关闭的表.
MEDIUM:扫描行,以验证被删除的连接是有效的,也可以计算各行关键字校验和.
EXTENDED:最全面的的检查,对每行关键字全面查找.
3、优化表:使用OPTIMIZE关键字,如OPTIMIZE [LOCAL|NO_WRITE_TO_BINLOG] TABLE user;
LOCAL|NO_WRITE_TO_BINLOG都是表示不写入日志.,优化表只对VARCHAR,BLOB和TEXT有效,通过OPTIMIZE TABLE语句可以消除文件碎片,在执行过程中会加上只读锁.
2.2 硬优化
2.2.1 硬件三件套
1、配置多核心和频率高的cpu,多核心可以执行多个线程.
2、配置大内存,提高内存,即可提高缓存区容量,因此能减少磁盘I/O时间,从而提高响应速度.
3、配置高速磁盘或合理分布磁盘:高速磁盘提高I/O,分布磁盘能提高并行操作的能力.
2.2.2 优化数据库参数
优化数据库参数可以提高资源利用率,从而提高MySQL服务器性能.MySQL服务的配置参数都在my.cnf或my.ini,下面列出性能影响较大的几个参数.
key_buffer_size:索引缓冲区大小
table_cache:能同时打开表的个数
query_cache_size和query_cache_type:前者是查询缓冲区大小,后者是前面参数的开关,0表示不使用缓冲区,1表示使用缓冲区,但可以在查询中使用SQL_NO_CACHE表示不要使用缓冲区,2表示在查询中明确指出使用缓冲区才用缓冲区,即SQL_CACHE.
sort_buffer_size:排序缓冲区
传送门:更多参数
https://www.mysql.com/cn/why-mysql/performance/index.html
2.2.3 分库分表
因为数据库压力过大,首先一个问题就是高峰期系统性能可能会降低,因为数据库负载过高对性能会有影响。另外一个,压力过大把你的数据库给搞挂了怎么办?所以此时你必须得对系统做分库分表 + 读写分离,也就是把一个库拆分为多个库,部署在多个数据库服务上,这时作为主库承载写入请求。然后每个主库都挂载至少一个从库,由从库来承载读请求。
2.2.4 缓存集群
如果用户量越来越大,此时你可以不停的加机器,比如说系统层面不停加机器,就可以承载更高的并发请求。然后数据库层面如果写入并发越来越高,就扩容加数据库服务器,通过分库分表是可以支持扩容机器的,如果数据库层面的读并发越来越高,就扩容加更多的从库。但是这里有一个很大的问题:数据库其实本身不是用来承载高并发请求的,所以通常来说,数据库单机每秒承载的并发就在几千的数量级,而且数据库使用的机器都是比较高配置,比较昂贵的机器,成本很高。如果你就是简单的不停的加机器,其实是不对的。所以在高并发架构里通常都有缓存这个环节,缓存系统的设计就是为了承载高并发而生。所以单机承载的并发量都在每秒几万,甚至每秒数十万,对高并发的承载能力比数据库系统要高出一到两个数量级。所以你完全可以根据系统的业务特性,对那种写少读多的请求,引入缓存集群。具体来说,就是在写数据库的时候同时写一份数据到缓存集群里,然后用缓存集群来承载大部分的读请求。这样的话,通过缓存集群,就可以用更少的机器资源承载更高的并发。
结语
一个完整而复杂的高并发系统架构中,一定会包含:各种复杂的自研基础架构系统。各种精妙的架构设计.因此一篇小文顶多具有抛砖引玉的效果,但是数据库优化的思想差不多就这些了.
关于mysql的项目_项目中常用的MySQL 优化相关推荐
- 在工作中mysql常用知识_工作中常用的mysql命令
1.啟動數據庫 #啟動mysql(skip-name-resolve參數是必須的) su - mysql -c "mysqld_safe --skip-name-resolve --open ...
- 项目中常用的MySQL优化你知道多少?
项目中常用的MySQL优化 文章目录 项目中常用的MySQL优化 前言 一.mysql优化是什么? 二.优化步骤 1.EXPLAIN 2.SQL语句中IN包含的值不应太多 3.SELECT语句务必指明 ...
- 在MySQL的InnoDB存储引擎中count(*)函数的优化
转载自 在MySQL的InnoDB存储引擎中count(*)函数的优化 写这篇文章之前已经看过了很多数据库方面的优化内容,大部分都是加索引.使用事务.要什么select什么等等.然而,只是停留在阅读 ...
- 学习【瑞吉外卖⑪】SpringBoot单体项目_项目优化
若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 本人写这篇博客旨在制作学习笔记,巩固知识.同时方便个人在线阅览,回顾知识. 这篇博客中主要对应[瑞吉外卖项 ...
- hashmap应用场景_工作中常用到的Java集合有哪些?应用场景是什么?
秋招Java面试大纲:Java+并发+spring+数据库+Redis+JVM+Netty等 疫情期间"闭关修炼",吃透这本Java核心知识,跳槽面试不心慌 Spring全家桶笔记 ...
- mysql数据库管理文件_数据库管理中文件的使用教程
摘要:这篇MySQL栏目下的"数据库管理中文件的使用教程",介绍的技术点是"数据库管理.使用教程.数据库.的使用.文件.管理",希望对大家开发技术学习和问题解决 ...
- mysql数据库管理文件_数据库管理中文件的使用_MySQL
bitsCN.com 数据库管理中文件的使用 从文本文件中读取数据(import) 常用的文本文件:CSV(Comma Separated Values)文件,即:以逗号分隔的数值 形式如下: [pl ...
- MySQL—数仓ETL开发中常用到的日期函数
在数据仓库ETL开发中,当以增量的方式进行数据同步时,会将数据表中的时间字段作为增量字段获取增量数据.对于MySQL数据库来说,总结了以下日期表示以及需要注意的问题. 一.需要注意的问题: 查看MyS ...
- mysql 时间查询_两种常用MySql查询时间段的方法
MySql查询时间段的方法很多,下面就为您介绍几种最常用的MySql查询时间段方法,如果您在MySql查询时间段方面遇到过问题,不妨一看. MySql的时间字段有date.time.datetime. ...
最新文章
- Redis缓存失效策略思考
- Android 进程常驻(使用第三方MarsDaemon)(虽然不可用,但是还是保留下。)
- Android蓝牙开发其二
- 第一节 HTML DOM
- Hadoop学习之Hadoop集群的定制配置(二)
- 深度学习(四)卷积神经网络Lenet-5实现
- Linux下MySql插入汉字报错解决(/etc/my.cnf不存在)
- [19/04/24-星期三] GOF23_创建型模式(建造者模式、原型模式)
- 安工大计算机学院肖维民,安工大路由器实验报告.docx
- 扩展类载入器的载入问题
- 节选转载:你敢向代码库中添加Boost你就等着被开除吧
- LINUX编译OpenJDK,也可以指定freetype
- 数据库系统概论--课后习题
- WPF 入门教程 TextBox详解
- Java基础语法(详细版)
- 谷仓加密方式_谷仓紧缩谷物如何导致苹果计算机
- selenium自动化图片不加载设置
- 华为:交付服务体系怎么提升一线作业人员的工作体验?
- 传统贸易企业数字化管理
- linux 查看CPU核数
热门文章
- 左右伸缩_SSFB梳齿型桥梁伸缩缝安装步骤及使用特性
- php发表图片文章代码,PHP实现发表文章时自动保存图片_php
- 如何绘制逻辑图 — 7.逻辑的表达:业务逻辑
- 2018中国国际大数据大会专属报名通道(粉丝专享)开通啦!
- 作者:赵菁华(1977-),女,中国电子技术标准化研究院高级工程师。
- 张庆余(1991-),男,北京卡达克数据技术中心软件业务本部助理工程师,主要研究方向为软件架构、云计算。...
- 一本可能引发社会调查行业革命的书
- 【C语言】第六章 集合数据与数组 题解
- 字符串的展开(洛谷P1098题题解,Java语言描述)
- 【Java】命令行生成JavaDoc文档