01如何发现有问题的SQL

Yishto 2018-03-20 20:45:50
Categories: Tags:
数据库是基于文件的,如果性能好,则要求内存大,IO输出速度快,SSD等,对CPU不是硬性的要求.

1. 使用慢查询日志进行监控.

1
2
3
4
show variables like 'slow_query_log'   //查询状态
set global slow_query_log_file='/home/mysql/sql_log/mysql-slow.log' //设置存储位置
set global log_query_not_using_indexes = on; //开始慢查询
set global log_query_time = 1 //超过 1 秒的为慢查询

慢查询日志所包含的信息:

  1. 执行SQL语句的主机信息.(用户,地址)
  2. SQL 的执行信息. (如执行所用时间)
  3. SQL 的执行的时间 (执行sql时候的时间 时间戳)
  4. SQL 语句的内容.

2. 慢查询的工具

  1. mysqldumpslow (安装完成就有,官方自带)
  1. pt-query-digest 工具
  1. 查询次数比较多的,占用时间长的SQL
  2. IO大的SQL(扫描的行数多的SQL,IO大,参考pt-query-digest 分析中的Rows examin项)
  3. 未命名索引的SQL

3. explain

使用方法如:

1
explain select * from users;

执行语句后返回各列的意义:

extra需要注意的返回值:

优化 count() 和 max() 的统计类函数 :

  1. 在统计的字段上添加索引 .
  2. 利用count(‘字段名’) 和 count() 的不同进行统计.
    (1). count(‘字段名’) 不包括 NULL
    (2). count(
    ) 包括NULL

**如 :**将下面的SQL语句进行优化(分别统计2016和2017的数据)

1
select count(time='2016' OR time='2017') from film   //优化前SQL实际是错误的
1
select count(time='2016' OR NULL) as 2016,count(time=2017 OR NULL) as 2017 from film    //优化后的SQL

子查询的优化 :

group by优化:

limit 查询优化 :

  1. 优化步骤一 :
    尽量使用主键排序 .
  2. 优化步骤二 :记录上次返回的主键,在下次查询时,使用主键过滤 .
    如:
    1
    select film_id,description from skia,film order by film_id limit 600,5;   //原SQL  扫描605行
    优化后:
    1
    select film_id,description from skia,film where film_id>600 and film_id<=605 order by film_id limit 0,5;    //扫描了5行

选择合适的列建立索引 :

  1. 在 where 从句 , group by 从句 , order by 从句 , on 从句 , 中出现的列.
  2. 索引字段的长度越小越好.
  3. 查询频繁的字段.
  4. 离散度(区分度)越大索引的效果越好.且把离散度(区分度)大的放在联合查询(AND)的前面最好 . (计算公式 : select count(distinct(name))/count(*) from 表名 结果范围 0-1.0 空表为0的结果除外 )
  5. 最左前缀匹配原则 : myqsl 会一直向左 , 直到遇到范围查询就会停止 (‘>’ , ‘<’ , ‘between’ , ‘not in’ , ‘not exist’ , ‘!=’ , like )等 , 故 , 将范围查询放在最左(后)面 .
  6. 在 SQL 里进行运算会使索引失效 .
  7. 扩展优先 , 修改索引的时候 , 尽量在已存在的索引中修改 , 而不是新建 .