网站首页 > 技术文章 正文
优化思路:
- 开启慢查询日志,查看哪些sql耗时长
- 查看执行慢的sql的执行计划(为优化提供方向)
- 优化查询sql(怎么优化)
- 使用【show profils】查看问题sql的使用情况(使用方法是啥)
- 调整操作系统参数优化(怎么调整)
- 升级服务硬件(什么条件下升级)
慢查询日志?
慢查询日志默认关闭的,开启的方法是mysql etc目录下的配置文件中my.cnf文件中修改参数slow_query_log=on或则是slow_query_log=1开启,开启后需要重启mysql。开启后会在var/lib/mysql生成mysql(跟hostname)-slow.log。其中会记录查询时间比较长的sql语句。其中时间比较长可以用long_query_time设置阈值(默认10s),慢查询日志可能重复的数据比较多,有个mysqldumpslow可以对慢查询日志进行排序。
例如:得到按照时间排序的前10条里面含有左连接的查询语句:
mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/slow.log
其中-s表示用什么方式进行排序:al 平均锁定时间、ar平均返回记录时间、at平均查询时间、c计数、l锁定时间、r返回记录、t查询时间
-t是top n的意思,返回前面多少条的数据
-g 后面可以跟正则表达式,大小写不敏感。
最后的慢查询日志的文件路径。
查看执行计划(explain)?
explain结果如上,id: 表示查询分配的唯一标识符、select_type: 查询的类型、table: 查询的表、partitions: 匹配的分区 、type: join 类型、 possible_keys: 此次查询中可能选用的索引、 key: 此次查询中确切使用到的索引、 ref: 哪个字段或常数与 key 一起被使用、 rows: 显示此查询一共扫描了多少行,这个是一个估计值、filtered: 表示此查询条件所过滤的数据的百分比 、extra: 额外的信息。
id相同执行顺序自上而下;id不同的话,若是有子查询,id会自增,id越大,优先级越高;id相同和不同同时存在,优先级高的先执行,相同的自上而下执行。
select_type
- simple表示不需要union操作或者不包含子查询的简单select查询。有连接查询时,外层的查询为simple。
- primary 一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type即为primary。
- subquery 除了from字句中包含的子查询外,其他地方出现的子查询都可能是subquery
- union连接的两个select查询,第一个查询是dervied派生表,除了第一个表外,第二个以后的表 select_type都是union
- union result 包含union的结果集,在union和union all语句中,因为它不需要参与查询,所以id字段为null
- dependent union 与union一样,出现在union 或union all语句中,但是这个查询要受到外部查询的影响
- dependent subquery 与dependent union类似,表示这个subquery的查询要受到外部表查询的影响
- derived from字句中出现的子查询,也叫做派生表,其他数据库中可能叫做内联视图或嵌套select
table
查询的表名,有如下几种情况: 如果查询使用了别名,那么这里显示的是别名 如果不涉及对数据表的操作,那么这显示为null 如果显示为尖括号括起来的就表示这个是临时表,后边的N就是执行计划中的id,表示结果来自于 这个查询产生。 如果是尖括号括起来的<union M,N>,也是一个临时表,表示这个结果来自于union查询 的id为M,N的结果集。
partitions
分区表(对于非分区表值为null)。 5.7之后的版本默认会有 partitions 和 filtered两列,但是5.6版本中是没有的,需要 使用explain partitions select ……来显示带有partitions 的列, 使用explain extended select ……来显示带有filtered的列。
type (可以看到sql有哪些问题)
显示的是单位查询的连接类型或者理解为访问类型,访问性能依次从好到差:
- system(系统表,特殊的const)
- const:使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const。
- eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描
- ref :非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单 独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体。
- fulltext:全文索引检索,要注意,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql不管代 价,优先选择使用全文索引
- ref_or_null:与ref方法类似,只是增加了null值的比较。实际用得不多。
- unique_subquery:用于where中的in形式子查询,子查询返回不重复值唯一值
- index_subquery 用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询 去重。
- range:用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询 去重。
- index_merge:表示查询使用了两个以上的索引,最后取交集或者并集,常见and ,or的条件使用了不同的索引,官方 排序这个在ref_or_null之后,但是实际上由于要读取所个索引,性能可能大部分时间都不如range
- index :select结果列中使用到了索引,type会显示为index
- all:select结果列中使用到了索引,type会显示为index
最少得到range这个值,all最差,代表全表扫描。all之上都可用索引。
possible_keys:此次查询中可能选用的索引,一个或多个;
key:查询真正使用到的索引,select_type为index_merge时,这里可能出现两个以上的索引,其他的 select_type这里只会出现一个。
key_len:key_len越小 索引效果越好。计算where条件后的,跟查询字段没关系。
ref:如果是使用的常数等值查询,这里会显示const;如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段;如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func
rows:这里是执行计划中估算的扫描行数,不是精确值(InnoDB不是精确的值,MyISAM是精确的值,主要原 因是InnoDB里面使用了MVCC并发机制)
filtered:filtered列指示将由mysql server层需要对存储引擎层返回的记录进行筛选的估计百分比,也就是说存储 引擎层返回的结果中包含有效记录数的百分比。最大值为100,这意味着没有对行进行筛选。值从100减 小表示过滤量增加。rows显示检查的估计行数,rows×filtered显示将与下表联接的行数。例如,如果 rows为1000,filtered为50.00(50%),则要与下表联接的行数为1000×50%=500。
extra :这个列包含不适合在其他列中显示单十分重要的额外的信息。
优化查询sql
1、索引优化
- 为搜索字段(where中的条件)、排序字段、select查询列,创建合适的索引,不过要考虑数据的 业务场景:查询多还是增删多?
- 尽量建立组合索引并注意组合索引的创建顺序,按照顺序组织查询条件、尽量将筛选粒度大的查询 条件放到最左边。
- 尽量使用覆盖索引,SELECT语句中尽量不要使用*。
- order by、group by语句要尽量使用到索引
- 索引长度尽量短,短索引可以节省索引空间,使查找的速度得到提升,同时内存中也可以装载更多 的索引键值。
- 太长的列,可以选择建立前缀索引
- 索引更新不能频繁,更新非常频繁的数据不适宜建索引,因为维护索引的成本。
- order by的索引生效,order by排序应该遵循最佳左前缀查询,如果是使用多个索引字段进行排 序,那么排序的规则必须相同(同是升序或者降序),否则索引同样会失效。
2、LIMIT优化
- 如果预计SELECT语句的查询结果是一条,最好使用 LIMIT 1,可以停止全表扫描
- 处理分页会使用到 LIMIT ,当翻页到非常靠后的页面的时候,偏移量会非常大,这时LIMIT的效率 会非常差。 LIMIT OFFSET , SIZE; LIMIT的优化问题,其实是 OFFSET 的问题,它会导致MySql扫描大量不需要的行然后再抛弃掉。 解决方案:单表分页时,使用自增主键排序之后,先使用where条件 id > offset值,limit后面只写 rows;
3、其他查询优化
- 小表驱动大表,建议使用left join时,以小表关联大表,因为使用join的话,第一张表是必须全扫描 的,以少关联多就可以减少这个扫描次数。
- 避免全表扫描,mysql在使用不等于(!=或者<>)的时候无法使用索引导致全表扫描。在查询的时 候,如果对索引使用不等于的操作将会导致索引失效,进行全表扫描;
- 避免mysql放弃索引查询,如果mysql估计使用全表扫描要比使用索引快,则不使用索引。(最典型的场景就是数据量少的时候);
- JOIN两张表的关联字段最好都建立索引,而且最好字段类型是一样的。
- WHERE条件中尽量不要使用not in语句(建议使用not exists);
- 合理利用慢查询日志、explain执行计划查询、show profile查看SQL执行时的资源使用情况。
使用【show profiles】查看问题sql的使用情况
Query Profiler是MySQL自带的一种query诊断分析工具,通过它可以分析出一条SQL语句的硬件性能瓶颈在什么地方。Profiler默认关闭,可以在mysql下使用set profiling=1 开启。
开启后可以通过show profile 和 show profiles 语句可以展示当前会话(退出session后,profiling重置为0) 中执行 语句的资源使用情况。
show profiles:查看已经分析过的sql语句列表;
show profile :具体某一条sql语句进行分析;
升级服务硬件
1、缓冲区优化
- 将数据保存在内存中,保证从内存读取数据 设置足够大的 innodb_buffer_pool_size (总内存的四分之三或则五分之四),将数据读取到内存中。
2、降低磁盘写入次数
- 对于生产环境来说,很多日志是不需要开启的,比如:通用查询日志、慢查询日志、错误日志
- 使用足够大的写入缓存 innodb_log_file_size (0.25*innodb_buffer_pool_size)
- 设置合适的innodb_flush_log_at_trx_commit,和日志落盘有关系。
3、服务器硬件优化
提升硬件设备,例如选择尽量高频率的内存(频率不能高于主板的支持)、提升网络带宽、使用SSD高 速磁盘、提升CPU性能等。
- CPU的选择: 对于数据库并发比较高的场景,CPU的数量比频率重要。
- 对于CPU密集型场景和频繁执行复杂SQL的场景,CPU的频率越高越好
- 上一篇: win10查看已连接的WiFi密码
- 下一篇: 使用CMD命令查看已“连接”wifi密码
猜你喜欢
- 2024-11-26 Win7\8\10下一条cmd命令可查得笔记本电脑连接过的Wifi密码
- 2024-11-26 一文搞懂MySQL行锁、表锁、间隙锁详解
- 2024-11-26 电脑的wifi密码忘记了?一招教你如何找回密码,简单明了,快收藏
- 2024-11-26 代码解决忘记密码问题 教你用CMD命令查看所有连接过的WIFI密码
- 2024-11-26 CMD命令提示符能干嘛?这些功能你都知道吗?
- 2024-11-26 性能测试之慢sql分析
- 2024-11-26 论渗透信息收集的重要性
- 2024-11-26 如何查看电脑连接过的所有WiFi密码
- 2024-11-26 详解mysql数据库性能优化实验--从两个sql来体会子查询的优化效果
- 2024-11-26 win10怎么查看已存储wifi密码
- 11-26Win7\8\10下一条cmd命令可查得笔记本电脑连接过的Wifi密码
- 11-26一文搞懂MySQL行锁、表锁、间隙锁详解
- 11-26电脑的wifi密码忘记了?一招教你如何找回密码,简单明了,快收藏
- 11-26代码解决忘记密码问题 教你用CMD命令查看所有连接过的WIFI密码
- 11-26CMD命令提示符能干嘛?这些功能你都知道吗?
- 11-26性能测试之慢sql分析
- 11-26论渗透信息收集的重要性
- 11-26如何查看电脑连接过的所有WiFi密码
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)