zoukankan      html  css  js  c++  java
  • Mysql复习

     

    想想基本上也一年多没有写复杂sql了!不写复杂sql的原因,一方面是为了减少复杂的笛卡尔积运算,节省数据库机器的资源;第二方面是为了让大部分数据尽量也命中缓存,如果是复杂的多表sql的话,一次更新操作可能就会将所有相关表的数据缓存失效掉!

    这次由于一个小型的春运项目,有同事写出了慢查询,导致系统半天无法进行有效访问!

    趁着这次sql优化,重新复习一下关于mysql的知识!

    将会从explain、profile、数据库引擎、日志信息进行再分析!

    Explain

    熟悉sql的同学都知道,一般小系统的话,我们为了省事提高人效,往往会使用复杂sql编写,这样能更快的开发,但是一不注意就容易写出效率奇慢的sql!笔者尤其非常感谢刚毕业时候的老大,第一项工作就将公司当时最复杂的一条sql交由我去处理,记得当时将sql折行之后语句有250行左右,当然毫无疑问这条sql也是非常慢的,所以也花了很长时间去优化,尤其是对于一个刚毕业的来说!庆幸,当时学了不少关于优化的东西,也对sql熟悉了不少,有点底子!

    优化sql,少不了这个sql利器,信息不多,但是能帮我们分析出一些问题来。

    首先,我们要知道要优化的表的数据结构,看下每个字段的数据类型;可以使用desc命令,在一条sql的排序中使用,同时也可以放在sql的最前边,如果后边跟的是表名,则会显示出该表字段的数据类型等信息

    desc tablename;

    或者我么可以使用show方法,查看创建该表时候的语句,

    Show create table tablename;

    这里也就确认保障了,如果添加了索引,比如某个只存储数据类型的字段,但是使用了varchar类型,当我们使用数字进行检索的时候,但是已经建立了索引,我们就利用不上索引了,所以索引的使用也必须保证同数据类型。

    当存在一个慢sql的时候,可以使用explain关键字查看他的查询情况与阻塞情况等,

    实际上,我们要有一个定式,就是尽量使用小数据的表,此处使用了大数据的表去关联,所以首先看到type类型是All全表扫描,而且rows扫描了近4万行。

    1、需以小表为主进行查询;

    2、In的使用,尤其是文档上说的,(摘自网络:

    If the inner and outer queries return M and N rows, respectively, the execution time becomes on the order of O(M×N), rather than O(M+N) as it would be for an uncorrelated subquery.

    An implication is that an IN subquery can be much slower than a query written using an IN(value_list) construct that lists the same values that the subquery would return.

    );说是使用这种方式,会以o(m*n)的复杂度进行计算,而不是以o(m + n),其实感觉还是比较容易理解的,可以想一下笛卡尔积的排列组合;数据库先从子表查询,然后依次对in内的数据扫描;

    改造方式,我们后续再说!现在首先要分析explain。

    可以看到进行过explain后的语句出现了10列2行的信息,分别对应着两张表的操作情况。

    Select_type:每个查询语句中的类型,表示一个复杂度;

    一般有simple、primary(包含复杂查询)、dependent、subquery(包含子查询)、union、dependent(依赖外层查询数据)、device(与dependent类似,只是表达了在驱动表后的查询),大概就记得这些吧。

    Type:访问的类型,分别有all、 index(遍历索引的树),  range(比如查找某一范围内的), ref(索引不唯一), eq_ref(性能更好的主键索引与唯一性索引), const(大概就是指where条件中指定的某值, system(说是const的特殊,表中只有一行的情况, null(这种级别算是索引优先之后,又优先了排序级别吧),性能一次升高。全表扫描肯定是优先避免的;

    Possible_key:表示可以使用的索引,索引类型有:主键索引、唯一性索引、普通索引、联合索引、全文索引;

    Key:表示实际可以使用的索引;

    Key_len:表示索引的字节长度;

    Ref:连接匹配条件,同时是在索引上的关联;

    Rows:不用多说,这个是扫描了的数据行;

    Extra:这个就比较多了,而且比较重要。有些说法是“十分重要的信息,但是并不显示”。存在的值为,using index(覆盖索引,被指定的列,非*)、 using where(检索索引后再过滤字段,并非只要有where的就有该值)、using temporary(临时表存储,尽量避免)、using filesort(无法利用索引的文件索引)、using join buffer(不仅join但凡连表操作中,存储引擎为了优化会使用join_buffer,提示了注意是否需要索引优化。有一篇文章比较容易理解:https://www.cnblogs.com/shengdimaya/p/7123069.html)、impossible where(没有符合条件的行)、select tables optimized away(利用索引从聚合函数返回仅一行)、index merge(包括using union等,表示多个索引的使用);

    基本上,大致的sql信息展示出来了,具体的没有展示,但是对于使用端来说是足够的。

    好了,根据上面的慢sql,我们来优化一下,首先就是改成小表为主驱动表;其次就是看他的ref信息类型能否更优;第三,不采用in关键字,尝试使用join级联;第四,查看扫描的数据行数;

    好了,再看一下,不再是全表扫描了,而且扫描行数只有19行,ref相关的索引也利用上了,毫无疑问性能会好很多。

    篇章二

      前边的explain用于分析逻辑问题没有问题,接下来是性能问题,我们比较常用的是Show profiles;该命令,用于追踪执行sql过程中资源消耗的情况!

    关于profiles这个工具,分析的东西就非常细致了,具体到内存,cpu的使用情况,同时包括cpu在sql执行的各个过程所用的时间。

    如果将一下开启流程,那也太没意思了,但是笔者记忆力不是很好,擅长的东西总是比较容易遗忘,所以还是记录一下吧。

    1、查看是否开启 show variables like ‘%profiling%’;如果看到profiling=ON则为开启,否则需要手动开启;

    2、没有开启,则开启 set profiling=1;

    3、执行要分析的sql

    4、使用show profiles;可以显示所有查询语句、持续时间、与查询id号;

     

    5、选取一个id,如选择3,进行分析,输入show profile all for query 3;

    6、该命令也可以不适用all命令 show profile for query;

    可以从概况中看到对应该sql执行过程,而且看的出来在哪个过程比较耗时

    毫无疑问,基本上耗时都在网络上,所以每次sql的传输,尽量减少数据量;

    7、同样如果查看cpu的状况的话,可以使用show profile cpu for query X;等等。

    基本上使用explain与profile两个工具的命令,就能确认sql的性能问题。

    篇章三

    关于mysql的日志!

    show variables like '%dir%'; 可以查看对应文件存放在什么目录!

    show variables like '%slow_query_log_file%'; 查看慢查询日志文件位置

    show variables like '%general_log%'; 查看普通sql日志位置、开启否

    show variables like '%log_error%'; 查看错误日志信息

    set global general_log=ON; 开启通用日志开关

    set global log_output='file,table'; 设置日志输出方式,可单独设置为file或table

    select * from mysql.general_log; 以数据表的形式查看普通日志;

    show variables like '%dir%'; 查看mysql相关的数据位置;

    开启binlog(主从复制、日志回复等),

    #log_bin=ON

    #log_bin_basename=C:ProgramDataMySQLMySQL Server 5.7Datainlog

    #log_bin_index=C:ProgramDataMySQLMySQL Server 5.7Datainlog.index

    #also this : log-bin=C:ProgramDataMySQLMySQL Server 5.7Datainlog

    #server-id=123454

    修改后,service mysqld restart,重启mysql服务

    等等......

    篇章四

    数据库的存储引擎、数据库存储文件不同格式的用处!

    数据库存储文件不同格式的用处

    通过show variables like ‘%dir%’;找到数据库存储数据的位置;

    C:ProgramDataMySQLMySQL Server 5.7Data

    随便查看一个数据库文件夹内的文件,发现有以下几种格式、

    简述这几种文件格式的用处:

    *.frm:描述了表的结构

    *.ibd:InnoDB引擎开启独立表空间存放该表的数据和索引的文件

    *.MYD:保存了表的数据记录

    *.MYI:是表的索引

    *.opt:存储当前数据库的默认字符集和字符校验规则

    数据库的存储引擎

    show engines;可以查看数据库的存储引擎!能看到很多引擎的方式:

    一般,对于业界用的比较多的也就四种:InnoDBMyISAMMEMORYMRG_MYISAM

    InnoDB:具有提交、回滚和崩溃恢复能力的事务安全对比MyISAM引擎,写的处理效率会差一些,并且会占用更多的磁盘空间以保留数据和索引。 

    MyISAM:不支持事务、也不支持外键,优势是访问速度快

    MEMORY:使用存在于内存中的内容来创建表,毫无疑问容易丢失;

    MRG_MYISAM:本身并没有数据,是Myisam的组合;

    一般,我们创建库、表的时候就指定了数据库的引擎,而且现在由于es、mongodb等nosql的出现,除了innodb,其他类型的引擎方式很少被用到,除非在一些不在意性能的系统上还存在。

    修改数据库引擎的话,可以修改配置文件my.cnf.

    [mysqld]后面添加default-storage-engine=InnoDB,重启服务

    后续再扩展其他mysql的知识!

     

     

  • 相关阅读:
    Android AsyncTask
    Eclipse 快捷键
    Android JSON数据的读取和创建
    Android 原生listview item伸展收缩效果 (续)
    Android 原生listview item伸展收缩效果
    Android listview 禁止滑动
    Android R.layout. 找不到已存在的布局文件
    Android ScrollView
    Android android:clickable 问题
    Codeforces 388C Fox and Card Game (贪心博弈)
  • 原文地址:https://www.cnblogs.com/kevinfuture/p/8536273.html
Copyright © 2011-2022 走看看