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

MySQL数据库调优

目录

测试数据准备    

SQL查询慢原因分析

开启SQL慢查询分析

​分析SQL执行计划

数据库诊断

索引

索引创建原则

索引失效分析及解决办法

特定查询语句分析 

JOIN语句

分页语句

​统计Count语句

排序Order By语句

分组Group By语句


测试数据准备    

        本文基于Mysql官网employees数据库进行模拟测试,环境准备如下:

        1、https://github.com/datacharmer/test_db 下载工程代码到本地

        2、安装employees数据库数据:mysql -u root -p123456 <employees.sql

        3、查看安装结果:mysql -u root -p123456 <test_employees_md5.sql

SQL查询慢原因分析

开启SQL慢查询分析

set global slow_query_log = 'on'; #开启慢查询
set global log_output = 'file,table';#慢查询日志记录到文件和表中
set global long_query_time = 0.1; #慢查询时间超过100毫秒则记录
set global log_queries_not_using_indexes = 'on';#开启查询未使用索引
show variables like '%slow_query_log_file%'; #显示慢查询日志记录的文件位置
select * from `mysql`.slow_log; #慢查询记录的结果数据

分析SQL执行计划

        explain可用来分析SQL的执行计划,示例如下:

        1)id相同,执行顺序从上往下
        2)id不同,id值越大,优先级越高,越先执行

        输出结果重点字段说明:

        1)type 联接类型,显示查询使用了何种类型,查询性能从最好到最坏排序如下(一般保证查询至少达到range级别,最好能达到ref)

        system:表中仅有一行(系统表)这是const联结类型的一个特例。

        const:针对主键或唯一索引的等值查询扫描,最多只返回一行数据.const 查询速度非常快,因为它仅仅读取一次即可。

        eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于唯一索引或者主键扫描。

        ref:非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,可能会找多个符合条件的行,属于查找和扫描的混合体。

        range:只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引,一般就是where语句中出现了between,in等范围的查询。这种范围扫描索引扫描比全表扫描要好,因为它开始于索引的某一个点,而结束另一个点,不用全表扫描。

        index:index 与all区别为index类型只遍历索引树,通常比all快,因为索引文件比数据文件小很多。

        all:遍历全表以找到匹配的行。

        2)possible_keys:可能的索引选择

        3)key:实际选择的索引

        4)rows:估计要扫描的行数

        5)filtered:表示符合查询条件的数据百分比

        6)Extra 重要的额外信息

        Using filesort:MySQL中无法利用索引完成排序操作称为“文件排序”。

        Using temporary:使用了临时表保存中间结果,mysql在查询结果排序时使用临时表。常见于排序order by和分组查询group by

        Using where :表明使用where过滤

数据库诊断

        常用的诊断命令如下:

命令        功能
show processlist ;#查看当前正在运行的线程信息 
show status ; #查看数据库服务器相关信息
show variables; #查看mysql变量
show table status from employees;#查看表的状态
show index from employees; #查看表的索引信息
show create table salaries#查看salaries建表语句信息,包含表所用的引擎及字符集信息,如ENGINE=InnoDB DEFAULT CHARSET=latin1
select version()#查看数据库版本

索引

        MySQL中,InnoDB存储引擎使用B+树(B+ Tree)的数据结构来存储索引。 

        主键索引(Primary Key Index):基于主键创建的索引,通常是表中唯一的标识符,叶子节点存储主键及数据。

        非主键索引(二级索引、辅助索引):基于表中的其他列创建的索引,叶子节点存储索引以及主键。例如where 二级索引 = xxx,系统先根据二级索引找到主键,然后根据主键找到数据。

        MySQL中的索引左前缀原则(Leftmost Prefix Principle)是设计索引以提高查询效率的重要规则。在MySQL中,当你为表中的列创建复合索引时,MySQL会按照索引列的顺序从左到右依次使用这些列。这意味着,如果一个查询的条件能够匹配索引的最左边的列,那么这个索引就会被使用。

        【示例】:表employees 新建了索引:first_name ,默认index-type=BTREE,观察以下执行计划:

 

        在某张表中,建立了复合索引index(name,age,sex),以下查询说明如下:

where age = 10 and sex = 1;#查询条件没有最左侧name,无法使用复合索引

索引创建原则

        以下情况适合建立索引:

        1、select语句,频繁作为where条件的字段

        2、update/delete语句的where条件

        3、需要分组、排序的字段

        4、distinct所使用的字段

        5、字段的值有唯一性约束

        6、对于多表查询,联接字段应创建索引,且类型务必保持一致

        以下情况不适合建立索引:

        1、表中记录很少

        2、查询条件很少用到的字段

        3、字段数据重复,通过索引选择不到很少的数据,比如sex(0:男,1女)之类的字段

索引失效分析及解决办法

        索引失效场景如下:

        1、索引字段参与表达式计算

        解决办法:前台传递数据库明确的值

 

        2、索引字段参与表达式计算--当成函数的参数,解决方法同1

        3、索引字段使用了左模糊,不符合索引左前缀原则

        解决办法:避免使用左模糊查询

        4、where使用or条件,部分字段没有索引导致有索引的字段也失效

        解决方法:last_name 也建立索引

        5、基于字符串字段建立的索引,查询时没有用引号

        解决方法:编写准确的sql

        6、不符合左前缀原则的查询,建立了复合索引,查询时不符合左前缀原则

        解决方法:根据实际业务调整索引顺序,将last_name字段放在复合索引的第一个字段,再次查询。

特定查询语句分析 

JOIN语句

        Sql中常见的join语句分为:inner join,left join,right join。使用join语句查询建议遵循如下原则:

        1、表join的字段尽量创建索引,并且字段类型要保持一致

        2、join的表不建议太多,尽量不要超过3张以上

        3、尽量减少扫描的行数,通过explain可以获取

分页语句

        如果表数据量很大,需要查询很大页数数据的需求,可以采用 覆盖索引+Join的方式提高查询效率,其中select emp_no from employees limit 300000,10 查询的是覆盖索引,示例如下:

-- 改造前查询需要 193毫秒
select * from employees limit 300000,10;
-- 改造后:查询需要 70毫秒
select * from employees e inner join (select emp_no from employees limit 300000,10) t
on e.emp_no = t.emp_no

统计Count语句

        1、count(*)和count(1)含义一样

        2、count(*)不会排除统计null的行,count(字段)会排除统计字段=null的行

排序Order By语句

        使用order by最高效的做法是:利用索引自带的默认排序,进而不要排序。基于B+Tree创建的索引天然就有顺序,如果order by字段就是索引字段,查询就很高效,不会出现Extra = filesort的低效情形,所以对于排序子句的优化就是防止出现filesort,如果实际业务filesort情形无法避免,考虑通过增大设置缓冲区大小(sort_buffer_size),进而减少临时文件的产生,进而提高查询效率,示例如下:

-- 按照salary升序排序就产生了Using filesort,耗时:707毫秒
explain
select * from salaries order by salary

-- 按照emp_no升序排序就不会产生Using filesort,耗时:34毫秒
explain
select * from salaries order by emp_no

-- 默认sort_buffer_size = 262144
show variables where Variable_name = 'sort_buffer_size';
-- 设置sort_buffer_size = 1024*1024 = 1m
set sort_buffer_size = 1024*1024;

分组Group By语句

        分组语句尽量避免出现临时表(临时表性能较差),示例如下:

http://www.lryc.cn/news/584656.html

相关文章:

  • C++ 中最短路算法的详细介绍(加强版)
  • 【养老机器人】核心技术
  • 深入拆解Spring核心思想之一:IoC
  • vue3中ref和reactive的使用、优化
  • 入门级别的Transformer模型介绍
  • Linux 内核日志中常见错误
  • 学习JNI 二
  • 机器学习1
  • Java线程池原理概述
  • Spring Boot:将应用部署到Kubernetes的完整指南
  • 什么?不知道 MyBatisPlus 多数据源(动态数据源)干什么的,怎么使用,看这篇文章就够了。
  • Windows安装DevEco Studio
  • 深入理解oracle ADG和RAC
  • 高并发导致重复key问题--org.springframework.dao.DuplicateKeyException
  • 企业电商平台搭建:ZKmall开源商城服务器部署与容灾方案
  • Java中实现线程安全的几种方式
  • 华为OD 周末爬山
  • 模块三:现代C++工程实践(4篇)第二篇《性能调优:Profile驱动优化与汇编级分析》
  • 关于k8s Kubernetes的10个面试题
  • 【牛客刷题】跳台阶(三种解法深度分析)
  • Java 21 核心技术:虚拟线程与结构化并发实战
  • Django专家成长路线知识点——AI教你学Django
  • Spring Boot + Javacv-platform:解锁音视频处理的多元场景
  • 处理Web请求路径参数
  • 小程序开发平台,自主开发小程序源码系统,多端适配,带完整的部署教程
  • GitHub上优秀的开源播放器项目介绍及优劣对比
  • PPT 倒计时工具:把控节奏,掌握时间,超简单超实用让演示游刃有余
  • 电脑息屏工具,一键黑屏超方便
  • C语言——预处理详解
  • ADVANTEST R4131 SPECTRUM ANALYZER 光谱分析仪