当前位置: 首页 > news >正文

MySQL笔记11

一、SQL优化

1.概念

  在应用的的开发过程中,由于初期数据量小,开发人员写 SQL 语句时更重视功能上的实现,但是当应用系统正式上线后,随着生产数据量的急剧增长,很多 SQL 语句开始逐渐显露出性能问题,对生产的影响也越来越大,此时这些有问题的 SQL 语句就成为整个系统性能的瓶颈,因此我们必须要对它们进行优化.

优化方法

  从设计上优化:如合理设计表结构、数据类型等。

  从查询上优化:优化SQL查询语句的写法等。

  从索引上优化:合理创建和使用索引,提升查询效率。

  从存储上优化:如优化存储引擎、表空间等。

2.优化技巧

(1)原则

  减小查询的数据量、提升SQL的索引命中率

(2)查询时尽量不要使用 *

  开发中为方便会用 * 代替所有字段,但这种写法对数据库性能不友好。

 原因:

  分析成本变高:增加SQL解析器的额外解析成本。

  网络开销变大:返回无意义数据多,网络数据包体积大。

  内存占用变高:SQL查到的结果集更大,占用内存也越多。

  维护性变差:增加业务维护量。

(3)连表查询时尽量不要关联太多表

  关联表过多会导致执行效率变慢、执行时间变长。
建议:

  交互型业务:关联表数量控制在5张以内。

  后台型业务:虽对用户体验要求低且业务复杂,但最好控制在16~18张以内(阿里开发规范要求控制在3张以内)。

(4)多表查询时一定要以小驱大

  先查询小表,再用小表的结果去大表中检索数据。写SQL时最好将小表放在前面,大表放在后面。

(5)不要使用like左模糊和全模糊查询

原因:

  like 以 % 开头(如 %xxx 、 %xxx% )会导致索引失效,触发全表查询,降低查询效率。

解决方案:

  如需模糊查询,应避免左模糊和全模糊;若确实需要,可建立全文索引,或在数据量较大时使用ES、Solr等搜索引擎替代。

(6)查询时尽量不要对字段做空值判断

  对字段进行 is null 或 not is null 判断时,索引会失效,导致全表扫描。

如:

优化建议:

  设计字段时尽量用 not null 定义,若字段需为空,可用 0 、空字符串 "" 等空字符代替,这样查询空值时可通过空字符走索引检索。

(7)不要在条件查询 = 前对字段做任何运算

  即使字段建立了索引,这类操作还是会导致索引失效,触发全表查询。因为如果MySQL优化器字段前有运算,生成执行计划时不会为运算后的字段选择索引。

如:

(8)!=、!<>、not in、not like、or...要慎用

  这些操作可能会导致索引失效。

如:

  上述SQL虽然变长了,但查询效率会而更高,因为后面的SQL可以走索引

(9)避免频繁创建、销毁临时表

  临时表是数据缓存,对常用查询结果建立临时表可基于内存快速查询(速度远快于磁盘检索)。

注意事项:

  仅对频繁查询的数据建立临时表,盲目无限制创建、销毁会给MySQL带来较大负担。

(10)从业务设计层面减少大量数据返回的情况

  一次性返回大量数据会引发网络阻塞、内存占用过高、资源开销大等问题。

优化建议:

  若业务存在一次性返回全量数据的情况,需拆分业务逻辑,例如分批返回数据给客户端。

(11)尽量避免深分页的情况出现

如:

  这类深分页SQL,MySQL会先查询出100010条数据,再丢弃前10万条,仅返回最后10条,极其浪费资源。

改进方法:

  情况1(结果集有递增连续字段):基于有序字段筛选后再分页,如:

  情况2(搜索分页,结果无序):从业务上限制深分页,例如参考百度搜索,一般只提供前30页,避免用户进行极深分页操作。

(12)SQL务必要写完整,不要使用缩写法

示例:

注意:

  所有隐式的这种写法,在底层都需要做一次转换,将其转换为完整的写法,因此简写的SQL会比完整的SQL多一步转化过程,如果需要极致程度的优化,切记将SQL写成完整语法。

(13)明确仅返回一条数据的语句可以使用 limit 1

示例:

  上述这两条SQL语句都是根据姓名查询一条数据,但后者大多数情况下会比前者好,因为加上limit 1关键字后,当程序匹配到一条数据时就会停止扫描,如果不加的情况下会将所有数据都扫描一次。所以一般情况下,如果确定了只需要查询一条数据,就可以加上 limit 1提升性能。

(14)客户端的一些操作可以批量化完成

  批量新增某些数据、批量修改某些数据的状态...,若使用上述接口的结构,即insert语句嵌入在for循环中,由于每次都需要往MySQL发送SQL语句,则会带来额外的网络开销以及耗时,应更改为如下:

  上述修改,会组合成一条SQL发送给MySQL执行,能够在很大程度上节省网络资源的开销,提升批量操作的执行效率。

3.查看SQL执行频率

(1)作用

  MySQL 客户端连接成功后,通过 show [session|global] status 命令可以查看服务器状态信息。通过查看状态信息可以查看对当前数据库的主要操作类型。

(2)格式

查看当前会话统计结果(7个下划线):

查看自数据库上次启动至今统计结果:

查看针对Innodb引擎的统计结果:

(3)重要参数分析

参数含义
Com_select执行 select 操作的次数,一次查询只累加1
Com_insert执行 insert操作的次数,对于批量插入的 insert 操作,只累加一次
Com_update执行 update 操作的次数
Com_delete执行 delete 操作的次数
Innodb_rows_readselect 查询返回的行数
Innodb_rows_inserted执行 insert 操作插入的行数
Innodb_rows_updated执行 update 操作更新的行数
Innodb_rows_deleted执行 delete 操作删除的行数
Connections试图连接 MySQL 服务器的次数
Uptime服务器工作时间
Slow_queries慢查询的次数

(4)定位低效率执行SQL

可以通过以下两种方式定位执行效率较低的 SQL 语句:

  慢查询日志 : 通过慢查询日志定位那些执行效率较低的 SQL 语句。

  show processlist:该命令查看当前MySQL在进行的线程,包括线程的状态、是否锁表等,可以实时地查看 SQL 的执行情况,同时对一些锁表操作进行优化。

慢查询:

  查看慢日志配置信息:

  开启慢日志查询:

  查看慢日志记录SQL的最低阈值时间(单位为秒) :

  修改慢日志记录SQL的最低阈值时间,需要重启mysql服务:

show processlist:

分析:

  id列——用户登录mysql时,系统分配的"会话id",可以使用函数 connection_id() 查看

  user列——显示当前用户。如果不是root,这个命令就只显示用户权限范围的sql语句

  host列——显示这个语句是从哪个ip的哪个端口上发的,可以用来跟踪出现问题语句的用户

  db列——显示这个进程目前连接的是哪个数据库

  command列——显示当前连接的执行的命令,一般取值为休眠(sleep),查询(query),连接(connect)等

  time列——显示这个状态持续的时间,单位是秒

  state列——显示使用当前连接的sql语句的状态,很重要的列。state描述的是语句执行中的某一个状态。一个sql语句,以查询为例,可能需要经过copying to tmp table、sorting result、sending data等状态才可以完成

  info列——显示这个sql语句,是判断问题语句的一个重要依据

(5)explain 分析执行计划

作用:

  通过以上步骤查询到效率低的 SQL 语句后,可以通过 EXPLAIN 命令获取 MySQL如何执行 SELECT 语句的信息,包括在 SELECT 语句执行过程中表如何连接和连接的顺序。

格式:

  explain sql

示例:

分析:

字段含义
idselect 查询的序列号,是一组数字,表示的是查询中执行 select 子句或者是操作表的顺序。    
select_type表示 SELECT 的类型,常见的取值有 SIMPLE(简单表,即不使用表连接或者子查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(子查询中的第一个SELECT)等

table

输出结果集的表
partitions匹配的分区信息,若表未分区则为NULL,用于展示查询涉及的分区情况
type表示表的连接类型,性能由好到差的连接类型为(system --> const --> eq_ref --> ref --> ref_or_null --> index_merge --> index_subquery --> range --> index --> all )
prossible_keys表示查询时,可能使用的索引
key表示实际使用的索引

key_len

索引字段的长度
ref表示与索引列进行比较的列或常量,例如某列与另一列的关联、或列与常量的比较。NULL表示没有使用到基于列的索引关联
rows扫描行的数量
extra执行情况的说明和描述

参数使用:

  key:如果该值为空,则表示未使用索引查询,此时需要调整SQL或建立索引。

  type:这个字段决定了查询的类型,如果为index、all就需要进行优化。

  rows:这个字段代表着查询时可能会扫描的数据行数,较大时也需要进行优化。

  filtered:这个字段代表着查询时,表中不会扫描的数据行占比,较小时需要进行优化。

  Extra:这个字段代表着查询时的具体情况,在某些情况下需要根据对应信息进行优化。

(6)show profile 分析SQL

作用:

  show profiles 能够在做SQL优化时帮我们了解时间都耗费到哪里。

查看是否开启:

设置开启:

示例:

  通过 show profile for query query_id 语句可以查看到该SQL执行过程中每个线程的状态和消耗的时间:

  在获取到最消耗时间的线程状态后,MySQL 支持进一步选择 all、cpu、block io 、context switch、page faults 等明细类型类查看 MySQL 在使用什么资源上耗费了过高的时间。例如,选择查看CPU的耗费时间 :

分析:

字段含义
StatusSQL 语句执行的状态
DurationSQL 执行过程中每一个步骤的耗时
CPU_user当前用户占有的 CPU 
CPU_system系统占有的 CPU 

(7)trace 分析优化器执行计划

作用:

  MySQL 提供了对 SQL 的跟踪 trace , 通过 trace 文件能够进一步了解为什么优化器选择 A 计划, 而不是选择 B 计划。

方法:

  打开 trace ,设置格式为 JSON,并设置 trace 最大能够使用的内存大小,避免解析过程中因为默认内存过小而不能够完整展示。

示例:

(8)使用索引优化

作用:

  索引是数据库优化最常用也是最重要的手段之一, 通过索引通常可以帮助用户解决大多数的MySQL的性能优化问题。

建立原则:

  一般针对数据分散的关键字进行建立索引,比如ID、QQ,像性别、状态值等建立索引没有意

  对大数据量表建立聚集索引,避免更新操作带来的碎片

  尽量使用短索引,一般对int、char/varchar、date/time 等类型的字段建立索引

  需要的时候建立联合索引,但是要注意查询SQL语句的编写

  谨慎建立 unique 类型的索引(唯一索引)

  大文本字段不建立为索引,如果要对大文本字段进行检索,可以考虑全文索引

  频繁更新的列不适合建立索引

  order by 字句中的字段,where 子句中字段,最常用的sql语句中字段,应建立索引。

  对于只是做查询用的数据库索引越多越好,但对于在线实时系统建议控制在5个以内。

(9)架构优化

  业务拆分:搜索功能,like ,前后都有%,一般不用MySQL数据库

  业务拆分:某些应用使用nosql持久化存储,例如memcahcedb、redis、ttserver 比如粉丝关注、好友关系等;

  数据库前端必须要加cache,例如memcached,用户登录,商品查询

  动态数据静态化。整个文件静态化,页面片段静态化

  数据库集群与读写分离;

  单表超过2000万,拆库拆表,人工或自动拆分(登录、商品、订单等)

http://www.dtcms.com/a/470955.html

相关文章:

  • 网站前置审批在哪里办代理记账包含哪些业务
  • 河北品牌网站建设wordpress幻灯片源码
  • tp做的网站封装成app没有微信怎么进入公众号
  • 凡科网站的ftp手机网站怎么开发
  • 5G NR-NTN协议学习系列:NR-NTN介绍(5)
  • 企业建站都有什么网站什么网站可以在家做美工兼职
  • 网站导航栏设计代码乐山市规划和建设局门户网站
  • 青岛营销型网站制作做视频网站怎么挣钱吗
  • 网站前端跟后端怎么做wordpress登陆post
  • 网站开发建设成本河北城乡和住房建设厅官方网站
  • 能上国外网站的免费dns做电影网站需要注意什么软件
  • 网站制作的困难和解决方案怎样不让网站被收录
  • 自己做的网站被篡改怎么办江门网
  • 容桂佛山做app网站上海公司营业执照查询
  • 网站后台内容不更新宁波做网站设计
  • 建设银行信用卡网站是哪个外国网站签到做任务每月挣钱
  • 重庆门户网站华龙网wordpress新站SEO优化
  • 网站如何做seo排名网站制作关键字排名
  • 兰州网站制作怎么样购物便宜的网站有哪些
  • 怎么做算命网站WordPress出现503报错
  • 妇科医院网站建设怎么做自己制作app软件要多少钱
  • 6网站建设设计建设银行网站理财产品为何不让买
  • 点式高温计:全球市场格局与未来发展趋势
  • 网站排名和什么有关音乐网站建设论文
  • 同程旅行签到脚本
  • 制作微网站的平台wordpress videotheme
  • 信道编码的发展
  • 网站 栏目添加 文章不显示android开发视频
  • Mybatis(1)
  • 网站过程中遇到问题泉州有没有设计论坛app