日期:2014-05-16  浏览次数:20420 次

Mysql优化(深入浅出mysql数据库开发阅读笔记)
《深入浅出Mysql数据库开发、优化与管理维护》笔记
1、优化sql的一般步骤
  1.1 使用 show status 命令了解各种sql的执行频率
      进入mysql控制台执行
        show session status 查询当前连接的统计结果
        show global status 查询自数据库上次启动至今的统计结果

      或者在操作系统的终端执行
        mysqladmin extended-status
     
      可以通过like语句来查询一些特定的内容
      比如 show global status like "Com_%";就查看上次启动以来的每个Com_xxx语句执行的次数
     Com_select: 执行select查询的次数
     Com_insert: 执行insert的次数
     Com_update: 执行update的次数
     Com_delete: 执行delete的次数

     这些参数会都mysql所有存储引擎的表操作都做记录
     另外还有专门针对某一些存储引擎的,比如:
     Innodb_rows_read
     Innodb_rows_insert
     Innodb_rows_update
     Innobd_rows_delete

     通过上面这些数据的比较可以判断数据库是写为主,还是查询为主

     关于事务的信息 可以通过 Com_commit 和 Com_rollback 来了解提交和回滚的情况。如果回滚操作非常的频繁,说明应用编写存在很大的问题
    
     另外几个比较重要的,可以展示数据库基本情况的句子:
     Connections: 试图连接Mysql数据库的次数
     Uptime: 服务器工作时间
     Slow_queries: 慢查询的次数


   1.2 定位执行效率比较低的sql语句
      有两种方法:
      一、通过慢查询日志来定位。用--log-slow-queries[=filename]选项启动时,mysqld写一个包含所有执行时间超过long_query_time秒得sql语句的日志文件
      二、使用show processlist命令查看当前MySQL在进行的线程,包括线程的状态,是否锁表等,可以实时的查看sql的执行情况,同时对一些锁表操作进行优化。

   1.3 通过Explain分析低效SQL的执行计划
       再通过上面步骤,查到低效率的sql语句之后,可以通过 explain和desc命令获取mysql如何执行select语句的信息,包括select执行过程中表如何连接和连接的顺序。
       比如
explain select * from sum(money) from sales a, company b where a.company_id = b.id and a.year = 2006
+----+-------------+-------+--------+---------------+------+---------+------+------+---------------------+
| id | select_type | table | type   | possible_keys | key  | key_len | ref  | rows | Extra               |
+----+-------------+-------+--------+---------------+------+---------+------+------+---------------------+
|  1 | SIMPLE      | user  | system | NULL          | NULL | NULL    | NULL |    0 | const row not found |
+----+-------------+-------+--------+---------------+------+---------+------+------+---------------------+
1 row in set (0.00 sec)


       这个显示的结果是横向的,不够友好,在后面 追加参数“\G”可以每一项一列信息的显示
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: user
         type: system
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 0
        Extra: const row not found
1 row in set (0.00 sec)

ERROR:
No query specified

上面每一列的含义说明
   select_type: 表示select的类型(SIMPLE=>简单表,不使用表连接或者子查询,PRIMARY=>主查询,外层的查询,UNION=>UNION中的第二个或者后面的查询语句,SUBQUERY=>子查询中的第一个select)
   table; 输出结果集的表
   possible_keys: 表示查询时,可能使用的索引
   key: 表示实际使用的索引
   key_len: 索引字段的长度
   rows; 扫描的行的数量
   Extra: 执行情况的说明和描述
   type: 表示表的连接类型,性能有好到差的链接类型为:
      system=>只有一行,也就是常量表,
      const=>单表中最多有一个匹配行,例如primary key或者unique index,
      eq_ref=>对于前面的每一行,在此表中只查询一条记录,简单来说,就是多表连接中使用primary key或者unique index, 
      ref=>与eq_ref类似,区别在于不是使用primay key或者unique index而是使用普通的索引,
      ref_or_null=>与ref类似,区别在于条件中包含对null的查询,
      index_merge=>索引合并优化,
      unique_subquery=>in的后面是一个查询主键字段的子查询,
      index_subquery=>与unique_subquery类似,区别在于in的后面是查询非唯一索引字段的子查询,
      range=>单表中的查询范围,
      ind