MySQL优化

文章目录

  • 一、MySQL规范
    • 1、阿里MySQL规范
    • 2、开发规约
  • 二、模拟优化器Explain
    • 1、Explain 关键字
    • 2、模拟优化器执行后的返回参数介绍
  • 三、SQL优化
    • 1、SQL及索引优化
    • 2、系统参数优化
    • 3、InnoDB存储引擎
    • 4、慢查询日志
  • 总结

一、MySQL规范

1、阿里MySQL规范

  1. 表达是与否概念的字段,必须使用is_xxx的方式命名,数据类型是unsigned tinyint(0-255)(1表示是,0表示否)。无符号微整型。
    注意:POJO类中的任何布尔类型的变量,都不要加is前缀。数据库表示是与否的值,使用tinyint类型。
  2. 表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只出现数字。Linux默认是区分大小写的,所以不允许出现任何大写字母,避免节外生枝。正例:level3_name。
  3. 表名不使用复数名词。
    表名应该仅仅表示表里面的实体内容,不应该表示实体的数量,对于DO类名也是单数形式,符合表达习惯。
  4. 禁用保留字,例如desc、match、range等,即相当于Java的关键字。
  5. 主键索引名为pk字段名,唯一索引名为uk字段名,普通索引名为index。
    pk为primary key,uk为unique key,idx为index的简称。
  6. 小数类型为decimal,禁止使用float和double。
    float和double在存储时,存在精度损失的问题,很可能在值的比较时,得不到正确的结果。如果存储的范围超过decimal的范围,建议将数据拆分成整数和小数分开存储。
  7. 如果存储的字符串长度几乎相当,使用char定长字符串类型存储。
  8. varchar是可变长字符串,不预先分配存储空间,长度不要超过5000,如果存储长度大于此值,使用text字段类型,独立出来一张表,用主键来对应,避免影响其他字段索引效率。
  9. 表必备3字段,id,create_time,modified_time/update_time
    id为主键,类型为bigint unsigned (在实体类中对应Long),单表时自增,步长为1。
    create_time,modified_time/update_time的类型均为datetime类型,前者现在时表示主动创建,后者过去分词表示被动更新。
  10. 表的命名最好是业务名称_表
    正例:alipay_task / sys_user
  11. 如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释。
  12. 字段允许适当冗余,以提高查询性能,但必须考虑数据一致。冗余字段应遵循:不是频繁修改的字段,不是varchar超长字段,更不能是text字段。
    例如,商品单位使用的频率高,字段长度短,名称基本一成不变,可在相关联的表中冗余存储单位名称,避免关联查询。
  13. 合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检索速度。
    例如:
    1) 人的年龄在150岁之内,定义为tinyint unsigned,占用1个字节byte或8个bit,范围是无符号值的0~255。
    2)龟的年龄在数百岁之间,定义为smallint unsigned,占用2个字节byte或16个bit,范围是无符号值的0~65535。
    3)恐龙化石在数千万年之间,定义为int unsigned ,占用4个byte或32个bit,范围是无符号值的0~约42.9亿。
    4)太阳,约50亿年,定义为bigint unsigned,占用8个byte或64个bit,范围是无符号值的0~10的19次方
  14. 涉及金额,将其乘以100再进行存储,存储类型为整型(int或bigint)。例如66.66,存入数据库时为6666。

2、开发规约

  1. 写到应用程序的SQL语句,禁止一切Data Definition Language(DDL数据定义语言)操作。
    例如:Create table xxx ,Drop table xxx , Create database xxx ,Drop database xxx ,Alter table xxx grant … …

  2. 避免多余的排序。使用GROUP BY时,默认会进行排序。
    MySQL5.7在GROUP BY时,默认进行隐式排序。MySQL8.0时,取消该特性。

  3. 禁止select * 这样的代码,指定需要的字段名。

  4. 避免在where子句中对字段施加函数
    例如,select * from sys_user_log where substr(username,1,5)=‘abcde’

  5. 避免where子句中对字段进行表达式操作,避免在WHERE子句中对字段进行NULL值判断。

  6. 多表关联查询时,保证被关联的字段需要有索引,需要join的字段,数据类型必须绝对一致

  7. 使用ISNULL()来判断是否为NULL值,NULL与任何值的直接比较都为NULL,
    NULL<>NULL的返回结果是NULL,而不是false(<>即!=)
    NULL=NULL的返回结果是NULL,而不是true
    NULL<>1的返回结果NULL,而不是true

  8. 禁止使用存储过程,存储过程难以调试和扩展,更没有移植性

  9. 不得使用任何外键与级联,一切外键概念必须在应用层解决;
    外键与级联更新适用于单机低并发,不适合分布式、高并发集群;
    级联更新是强阻塞,存在数据库更新风暴的风险;
    外键影响数据库的插入速度。
    扩展:
    级联操作指的就是,当你操作主表时,自动的操作从表
    外键(foreign key) 是用于建立和加强两个表数据之间的链接的一列或多列; 外键约束主要用来维护两个表之间数据的一致性。

  10. 通过in条件更新一张表中的某些记录值,直接对子查询使用in的效率是很糟糕的,需要对in的子查询包一层。
    正例:

    update  xxx set name ="test" where id in(
    	select order_id from (
    		select order_id from xxx where name like "ct%") as tmp
    )
    

    即将in的子查询查出来的数据,再次通过select 取出来,存放在tmp临时表中,从而实现优化效果。

  11. 使用in操作时应控制里面的数据不超过1000条

  12. 尽量使用UNION ALL代替UNION
    因为UNION会执行去重和排序等操作,降低性能。可以在合并前先将数据处理好再合并。UNION ALL,即直接合并。

二、模拟优化器Explain

1、Explain 关键字

  1. Mysql 使用 explain 关键字可以模拟优化器执行 sql 语句,我们就能够知道 Mysql 会如何处理sql,可以根据 explain 的分析结果和Mysql 底层数据结构优化 sql。不同Mysql 版本可能有差别,但差别不会很大。
  2. 代码编写的顺序:
    select->distinct->from->join->on->where->group by->having->order by->limit
  3. Mysql读取顺序:
    from->on->join->where->group by->having->select->distinct->order by->limit
  4. 整体过程
    1)先对多表进行关联,根据条件找出符合的记录
    2)在符合的记录基础上进行where条件过滤
    3)对筛选出的记录进行分组操作
    4)分组完成后再进行having操作,过滤出满足条件的数据
    5)对取出的记录进行排序
    6)再按照分页条件取出要显示的数据

2、模拟优化器执行后的返回参数介绍

  1. id参数
    id:select查询的序号,表示执行select操作时表的顺序。
    id相同按顺序走
    id不同,序号大的先执行
    id相同与不同同时存在
  2. select_type参数
    查询类型,主要用于区别普通查询、联合查询、子查询
    SIMPLE:简单select查询,查询中不包含子查询或union;
    PRIMARY:主键查询
    SUBQUERY:where条件包含了子查询
    DERIVED:from的表中包含子查询,被标记为derived(衍生),把子查询的结果放在临时表中
  3. table:显示这一行的数据是来自于哪张表的
  4. partitions:如果查询是基于分区的话,会显示查询访问的分区
  5. type参数
    访问类型,按性能从低到高依次排列为
    ALL:全表扫描,一定要优化
    index:它和All都是扫描全表,但index是从索引中读取表,All
    是从硬盘中读取
    range:只检索给定范围的行,key列显示使用了哪个索引,
    between and或in等查询
    ref:非唯一性索引扫描,本质上也是一种索引访问
    eq-ref:唯一性索引扫描,对于每个索引键只有一条记录与之匹配
    const:通过索引一次就找到了,常见于primary或unique索引查找
    system:表中只有一行记录(系统表),很少出现
    NULL:不需要访问表
  6. possible_keys:显示可能应用在这张表中的索引,一个或多个,查询涉及的字段上若建立了索引则会列出来,但不一定被使用
  7. key:它和possible_keys的关系,理论上应该用到哪些索引(possible_keys),实际上用到了哪些索引(key)
  8. key_len:索引使用的字节数,key_len显示的值为索引字段的最大可能长度
  9. ref:索引是否被引用到,用到了哪几个索引
  10. rows:根据表统计信息及索引使用情况,估算所需读取的记录行数
  11. filtered参数:满足查询条件记录数量的比例,是百分比,不是具体的记录数,这个值越大越好,它依赖于统计信息,并不是很准确
  12. Extra参数
    1)Using filesort(文件排序,表示mysql无法利用索引完成排序操作)
    2) Using temporary(使用了临时表保存中间结果,常见于order by和group by)
    3) Using index(如果同时出现Using where,表明索引用来执行索引键值的查找,如果没有出现Using where,表明索引用来读取数据而非执行查找)
    4)Using where(使用了where过滤)
    5)Using join buffer(使用了连接缓存)
    6) impossible where(where子句的值总是false,不能用来获取记录)

三、SQL优化

1、SQL及索引优化

  1. 排序字段加索引
    即在ORDER BY排序时,对排序的字段需要建立索引,否则就会进行全表扫描(在Explain时,type的值为ALL)。
    即对查询进行优化,要尽量避免全表扫描,要在where 或order by涉及的字段上建立索引。
  2. where条件中,or两边的字段没有索引时,要尽量少用or。
    因为其中有一个不是索引字段,会造成查询不走索引。
  3. in和exists
    当in里面的子查询数据少可以用in,反之则用exists。
    即外层查询数据量大,内层查询数据量小用in;外层查询数据量小,内层查询数据量大用exists。
  4. 不建议使用%前缀模糊查询。
    因为这样会导致查询时索引失效,从而进行全表扫描。
    例如LIKE %name或%name%。
    但是%后缀模糊查询时,type为range。
  5. 避免在where子句中对字段进行表达式操作。
    例如 … where count*2=100,可以改成 … where count = 100/2
    如果对字段进行表达式操作会造成索引失效,导致全表扫描。不对字段进行表达式操作,则此时type为ref,即类型为非唯一索引。
  6. 对于联合索引来说,如果存在范围查询,如between and或<>等条件时,会造成后面的索引字段失效。
  7. 使用JOIN优化
    A left join B,A表为驱动表;A right join B,B表为驱动表。INNER JOIN时,MySQL会自动找出数据少的表作为驱动表。
    合理利用索引,被驱动表的索引字段作为on的限制字段。
    利用小表驱动大表,减少嵌套循环的循环次数,以减少IO总量和CPU的运算次数。
  8. 创建复合索引时注意顺序,要把常用字段放在前面。例如id,name是常用的,就要放在前边,不常用的放在后边。

2、系统参数优化

  1. 公共参数优化

    max_connections = 1000
    #同时处理最大连接数,推荐设置最大连接数是上限连接数的80%左右  
    sort_buffer_size = 2M
    #查询排序时缓冲区大小,只对order by和group by起作用,可增大此值为16M
    open_files_limit = 10240
    #MySQL打开的文件描述符限制,默认最小1024
    connect-timeout = 10
    #连接超时之前的最大秒数,Linux 平台上,该超时也用作等待服务器首次回应的时间
    wait-timeout = 28800
    #等待关闭连接的时间
    max_allowed_packet = 64M
    # 服务所能处理的请求包的最大大小以及服务所能处理的最大的请求大小(当与大的BLOB 字段一起工作时相当必要), 避免超长SQL的执行有问题,默认值为16M
    table_cache = 512
    # 所有线程所打开表的数量. 增加此值就增加了mysqld所需要的文件描述符的数量
    thread_stack = 192K
    # 线程使用的堆大小. 此容量的内存在每次连接时被预留.MySQL 本身常不会需要超过 64K
    thread_cache_size = 20
    # 我们在 cache 中保留多少线程用于重用.当一个客户端断开连接后,如果 cache 中的线程还少于 thread_cache_size,则客户端线程被放入 cache 中.这可以在你需要大量新连接的时候极大的减少线程创建的开销(一般来说如果你有好的线程模型的话,这不会有明显的性能提升.)服务器线程缓存这个值表示可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中,如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如果有很多新的线程,增加这个值可以改善系统性能。通过比较ConnectionsThreads_created 状态的变量,可以看到这个变量的作用根据物理内存设置规则如下:
    # 1G —> 8
    # 2G —> 16
    # 3G —> 32
    thread_concurrency = 8
    #该参数取值为服务器逻辑CPU数量×2,在本例中,服务器有 2颗物理CPU,而每颗物理CPU又支持H.T超线程,所以实际取值为4 × 28.设置 thread_concurrency的值的正确与否,对 mysql 的性能影响很大, 在多个 cpu(或多核)的情况下,错误设置了 thread_concurrency 的值, 会导致 mysql 不能充分利用多 cpu(或多核),出现同一时刻只能一个 cpu(或核)在工作的情况。 thread_concurrency 应设为 CPU 核数的 2.比如有一个双核的 CPU, 那么thread_concurrency 的应该为 4; 2 个双核的cpu,thread_concurrency 的值应为 8,属重点优化参数
    

    thread_concurrency参数对性能的影响比较大,即线程并发数

  2. MySQL常用有两种存储引擎,一个是MyISAM,不支持事务处理,读性能处理快,表级别锁。另一个是InnoDB,支持事务处理(ACID),设计目标是为处理大容量数据发挥最大化性能,行级别锁。

  3. MyISAM存储引擎参数优化
    1) MyISAM存储引擎对性能影响较大的参数是key_buffer_size、sort_buffer_size、read_buffer_size
    2)参数

    key_buffer_size = 256M
    #指定用于索引的缓冲区大小,增加它可得到更好的索引处理性能。如果是以InnoDB引擎为主的DB,专用于MyISAM引擎的key_buffer_size 可以设置较小,8MB 已足够 如果是以MyISAM引擎为主,可设置较大,但不能超过4G. 在这里,强烈建议不使用MyISAM引擎,默认都是用InnoDB引擎.注意:该参数值设置的过大反而会使服务器整体效率降低!
    sort_buffer_size = 2M
    #查询排序时所能使用的缓冲区大小。排序缓冲被用来处理类似ORDER BY以及GROUP BY队列所引起的排序。注意:该参数对应的分配内存是每连接独占!如果有100个连接,那么实际分配的总共排序缓冲区大小为100 × 2200MB,所以,对于内存在 4GB 左右的服务器推荐设置为 6-8M。
    read_buffer_size = 1M
    #读查询操作所能使用的缓冲区大小。和sort_buffer_size一样,该参数对应的分配内存也是每连接独享!如果机器内存是16G,可分配1MB用来做MyISAM表全表扫描的缓冲大小。当全表扫描需要时,在对应线程中分配.
    join_buffer_size = 512
    #联合查询操作所能使用的缓冲区大小,默认大小512KB,该参数对应的分配内存也是每连接独享。多表关联查询时,当JOIN key无索引时会用到join_buffer_size,此属性是在没有索引的情况下减少过多的表扫描而设计的。
    read_rnd_buffer_size = 8M
    #MyISAM 以索引扫描(Random Scan)方式扫描数据的buffer大小,如果程序中有很多order by语句,增大此属性值能够提升性能。
    bulk_insert_buffer_size = 64M
    #用来缓存批量插入数据的时候临时缓存写入数据。如果有大量数据插入可提高此参数值,默认是8M
    myisam_sort_buffer_size = 64M
    #MyISAM设置恢复表之时使用的缓冲区的尺寸,默认为8M,最小值4k。当在REPAIR TABLE 或用 CREATE INDEX 创建索引或ALTER TABLE过程中对MyISAM索引排序时分配的缓冲区
    myisam_max_sort_file_size = 10G
    #mysql重建索引时允许使用的临时文件最大大小,在windows系统中默认值为2G
    myisam_repair_threads = 1
    #如果该值大于1,在 Repair by sorting 过程中并行创建MyISAM 表索引(每个索引在自己的线程内).如果一个表拥有超过一个索引, MyISAM 可以通过并行排序使用超过一个线程去修复他们.这对于拥有多个 CPU 以及大量内存情况的用户,是一个很好的选择.
    myisam_recover = DEFAULT
    #Myisam_revocer控制了Myisam查找和修复错误的方式,DEFAULT--Mysql会尝试修复被标记为崩溃会没有干净关闭的表,除了修复,不会做任何事情;Backup--Mysql将数据文件备份到一个BAK文件中;FORCE--即使.MYD文件丢失的数据多余一行,恢复也会继续.
    transaction_isolation = REPEATABLE-READ
    # 设定默认的事务隔离级别.可用的级别如下:READUNCOMMITTED, READ-COMMITTED, REPEATABLEREAD,SERIALIZABLE,1.READ UNCOMMITTED-读未提交2.READ COMMITTE-读已提交 3.REPEATABLE READ -可重复读 4.SERIALIZABLE -串行
    

3、InnoDB存储引擎

  1. InnoDB存储引擎参数

    innodb_file_per_table = 1
    # InnoDB为独立表空间模式,每个数据库的每个表都会生成一个数据空间
    # 独立表空间优点:
    # 1.每个表都有自已独立的表空间。
    # 2.每个表的数据和索引都会存在自已的表空间中。
    # 3.可以实现单表在不同的数据库中移动。
    # 4.空间可以回收(除drop table操作外,表空间不能自已回收)
    # 缺点:
    # 1.单表增加过大,如超过100G
    # 结论:
    # 共享表空间在Insert操作上稍有优势。其它都没独立表空间表现好。当启用独立表空间时,请合理调整:
    innodb_open_files
    innodb_status_file = 1
    #启用InnoDB的status file,便于管理员查看以及监控等
    innodb_open_files = 2048
    # 限制Innodb能打开的文件数量,如果库里的表特别多的情况,请增加这个。这个值默认是300
    innodb_additional_mem_pool_size = 128M
    #设置InnoDB存储引擎用来存放数据字典信息以及一些内部数据结构的内存空间大小,默认是8M,数据库中表越多这个参数应设置得越大。所以当我们一个MySQL Instance中的数据库对象非常多的时候,是需要适当调整该参数的大小以确保所有数据都能存放在内存中提高访问效率的。
    innodb_buffer_pool_size = 128M
    #包括数据页、索引页、插入缓存、锁信息、自适应哈希索引、数据字典信息.InnoDB 使用一个缓冲池来保存索引和原始数据,不像MyISAM,这里你设置越大,你在存取表里面数据时所需要的磁盘 I/O 越少。在一个独立使用的数据库服务器上,你可以设置这个变量到服务器物理内存大小的80%,但不要设置过大,否则,由于物理内存的竞争可能导致操作系统的换页颠簸
    innodb_write_io_threads = 4
    innodb_read_io_threads = 4
    # innodb使用后台线程处理数据页上的读写 I/O(输入输出)请求,根据你的 CPU 核数来更改,默认是4
    # 注:这两个参数不支持动态改变,需要把该参数加入到my.cnf里,修改完后重启MySQL服务,允许值的范围从 1-64
    innodb_data_home_dir = /usr/local/mysql/var/
    #设置此选项如果你希望 InnoDB 表空间文件被保存在其他分区.默认保存在 MySQL 的 datadir 中.
    innodb_data_file_path = ibdata1:500M;ibdata2:2210M:autoextend
    #InnoDB将数据保存在一个或者多个数据文件中成为表空间.如果你只有单个逻辑驱动保存你的数据,一个单个的自增文件就足够好了.其他情况下.每个设备一个文件一般都是个好的选择.你也可以配置InnoDB来使用裸盘分区
    innodb_file_io_threads = 4
    #用来同步 IO 操作的 IO 线程的数量. 此值在 Unix 下被硬编码为 4,但是在 Windows 磁盘 I/O 可能在一个大数值下表现的更好.
    innodb_thread_concurrency = 0
    #在 InnoDb 核心内的允许线程数量,InnoDB 试着在 InnoDB内保持操作系统线程的数量少于或等于这个参数给出的限制,最优值依赖于应用程序,硬件以及操作系统的调度方式.过高的值可能导致线程的互斥颠簸.默认设置为 0,表示不限制并发数,这里推荐设置为0,更好去发挥CPU多核处理能力,提高并发量
    innodb_flush_log_at_trx_commit = 1
    #可以通过修改此参数的默认值,即批量提交事务IO的方式来提高数据库性能。但是当数据库crash的时候可能会丢事务。如设置为1,只要事务一提交,就会对Log buffer进行刷盘。
    innodb_log_buffer_size = 8M
    #用来缓冲日志数据的缓冲区的大小.当此值快满时, InnoDB将必须刷新数据到磁盘上.由于基本上每秒都会刷新一次,所以没有必要将此值设置的太大(甚至对于长事务而言)
    innodb_log_file_size = 500M
    #事务日志大小.在日志组中每个日志文件的大小,你应该设置日志文件总合大小到你缓冲池大小的5%~100%,来避免在日志文件覆写上不必要的缓冲池刷新行为.不论如何, 请注意一个大的日志文件大小会增加恢复进程所需要的时间.
    innodb_log_files_in_group = 2
    #在日志组中的文件总数,通常来说2~3是比较好的.
    innodb_log_group_home_dir = /usr/local/mysql/var/
    # InnoDB的日志文件所在位置. 默认是与innodb_data_home_dir参数值相同。
    innodb_lock_wait_timeout = 50
    #设置锁等待的时间默认是50s,一旦数据库锁超过这个时间就会报错,避免在资源有限的情况下产生太多的锁等待。
    innodb_flush_method = O_DSYNC
    #这个参数控制着innodb数据文件及redo log的打开、刷写模式.默认值是 “fdatasync”, 调用fsync()去刷数据文件与redo log的buffer;另一个是 “O_DSYNC”,innodb会使用O_SYNC方式打开和刷写redo log,使用fsync()刷写数据文件;设为O_DIRECT时,innodb使用O_DIRECT打开数据文件,使用fsync()刷写数据文件跟redo log
    innodb_force_recovery=1
    # 如果你发现 InnoDB 表空间损坏, 设置此值为一个非零值可能帮助你导出你的表.1 开始并且增加此值知道你能够成功的导出表。这个参数只能修改my.cnf配置文件,然后重启数据库实例,不能用命令行修改。
    innodb_fast_shutdown
    # 0,代表当MYSQL关闭时,Innodb需要完成所有full purge和merge insert buffer操作,这需要花费时间来完成;
    # 1,是默认值,不需要完成full purge和merge insertbuffer操作,但是在缓冲池的一些数据脏页还是会刷新到磁盘;
    
  2. InnoDB引擎参数中对性能影响较大的参数是innodb_buffer_pool_size

4、慢查询日志

  1. MySQL慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阈值的语句,具体指运行时间超过long_query_time值的SQL语句会被记录到慢查询日志中。

  2. 开启慢查询日志
    默认情况下,MySQL并不会开启慢查询日志,需要手动去设置这个参数,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询会降低服务器的性能。
    1)进入MySQL终端,查看是否开启慢查询日志,默认是OFF:show variables like "%slow_query_log%;"
    2)开启慢查询:set global slow_query_log =1;
    3)关闭慢查询:set global slow_query_log =0;
    4)这样开启只对当前数据库生效,重启之后将恢复默认值,如果要永久生效必须修改MySQL配置文件,即在my.cnf文件中添加以下内容:

    slow_query_log=1
    slow_query_log_file=慢查询日志存放的路径
    

    5)查询慢查询的阈值:show variables like "%long_query_time%";
    6)修改慢查询的阈值:set global long_query_time = 8;
    修改完慢查询的阈值后,需要重新连接MySQL客户端才会生效。
    7)查询慢查询语句的记录条数:show global status like "%slow_queries%";

  3. mysqldumpslow慢查询日志分析
    使用mysqldumpslow命令对慢查询日志进行分析。
    命令参数:
    1)-s 按照哪种方式排序(al, at, ar, c, l, r, t), 默认按at排序
    2)c 访问计数
    3)l 锁定时间
    4)r 返回记录
    5)t 查询时间
    6)al 平均锁定时间
    7)ar 平均访问记录数
    8)at 平均查询时间
    9)-t 是top n 的意思,即返回多少条数据
    10)-g 可以跟正则表达式,大小写不敏感
    11)得到返回记录数最多的10条sql:mysqldumpslow -s r -t 10 /var/lib/mysql/192-slow.log;
    12)得到访问次数最多的10条sql:mysqldumpslow -s c -t 10 /var/lib/mysql/192- slow.log;
    13)得到慢查询日志里包含left join的sql语句:mysqldumpslow -s t -g 'left join' /var/lib/mysql/192-slow.log;
    14)如果慢查询日志中sql语句太多,可结合|more使用:mysqldumpslow -s c /var/lib/mysql/192-slow.log|more;

  4. 慢查询show profiles
    show profiles是mysql提供的可以用来分析当前会话中sql语句执行的资源消耗情况的工具,可用于sql调优的参考。同样和慢日志查询一样,默认是处于关闭状态,并保存最近15次的运行结果。
    1)查看当前JDK版本是否支持:show variables like "%profiling%";
    如果hava_profiling的值为true,即支持。
    profiling默认值为OFF,即默认关闭状态。
    profiling_history_size默认为15次。
    2)开启profiling:set profiling = on;
    3)查看搜集的慢查询SQL语句:show profiles;
    4)诊断sql:show profile cpu,block io for query 5;
    当出现下面的数据时就要进行优化了
    converting HEAP to MyISAM #查询结果太大,内存放不下了,需要往磁盘上写
    creating tmp tables #创建临时表,先copy数据到临时表,用完再删除
    copying to tmp table on disk #把内存中的临时表复制到磁盘上
    locked #被锁定

总结

  1. show profiles命令的作用是分析慢查询sql语句
  2. mysqldumpslow命令的作用是分析慢查询日志
  3. MySQL的SQL语句优化主要是避免全表扫描,查询时尽量使用索引。访问类型Type至少达到range。
  4. 不使用%当前缀的模糊查询;in子查询时在外面再包一层临时表存储;在where时不对字段进行表达式操作;对order by 、group by等操作的字段建立索引。

你可能感兴趣的:(mysql,数据库,java)