`

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=>单表中的查询范围,
      index=>对于前面的每一行,都通过查询索引来得到数据,
      all=>对于前面的每一行,都通过全表扫描来得到数据


   
2 索引问题
  2.1 索引的存储分类
     MyISAM存储索引的表的数据和索引是自动分开存储的,各自是独立的文件
     InnoDB存储引擎的表的数据和索引是存储在同一个表的空间里面,但是可以有多个文件组成
     Mysql中的存储类型木匾只有两种,BTREE和HASH,具体情况和表的存储引擎有关。
     MyISAM和InnoDb存储引擎都支持BTREE索引,
     MEMORY/HEAP存储引擎可以支持HASH和BTREE索引
    
     mysql不支持函数索引,但是能对队列的前面的某一部分进行索引,例如name字段,可以只取name的前四个字符来进行索引。

2.2 使用索引
     对相关列使用索引是提高select性能的最佳途径
     使用索引的条件:a、查询条件中有索引关键字,b、多列索引只有查询条件使用了多列关键字最左边的前缀时,才可以使用索引,否则将不能使用索引。
    2.2.1 使用索引
     一下情况中会使用到索引:
     (1) 多列索引,只要查询的条件中用到了最左边的列,索引一般就会被使用
     (2) 对于使用like查询,后面如果是常量,只有%号不在第一个字符时,索引才可能被用到 比如 like "%3" 不会用索引, like "3%"就会走索引
     (3) 对大文本进行搜索的时候,使用全文索引,而不是使用 like '%...%'
     (4) 如果列名是索引,使用column_name is null将使用索引,
      例如: select * from aaa where name is null(name是索引列)
    2.2.2 存在索引但不使用索引
      在下列情况下,虽然mysql存在索引,但是并不会使用到索引
     (1)如果Mysql估计使用索引比全表扫描更慢,则不使用索引。例如如果列key_1 均匀分布在1和100之间,那么查询 select * from table where key_1 > 1 and key_1 < 90;
     (2)如果使用MEMPRY/HEAP表并且,where条件中不使用“=”进行索引列,那么不会用到索引。heap表只有在使用“=”的时候,才使用索引
     (3)用or隔开的条件,如果or前面的列中有索引,而后面的列中没有索引,那么涉及的索引都不会被用到(or中有一个条件中的列没有索引就用不到索引)
     (4)如果不是索引列的第一部分(复合索引的第一部分)
     (5)如果like是%开始的
     (6)如果列类型是字符串,那么一定记得在where条件中把字符常量值用引号引起来,否则即便是这个列上有索引,也不用用到(比如name字段是字符串的,却写了name=123。要改成“123”)
    
   2.3 查看索引使用情况
    如果索引正在工作,Handler_read_key的值将很高,这个值代表了一个行被索引值读的次数,很低得知表明增加索引得到的性能改善不高
    Handler_read_rnd_next的值高则意味着查询的效率低效,并且应该建立索引补救。它的含义是:数据文件中读下一行的请求数。如果正在进行大量的表扫描,Handle_read_rnd_next的值较高,则通常说明表索引不正确或者写入的查询没有利用索引
    查看方法:show status like 'Handler_read%'

3 简单的优化方法
   3.1 定期分析表和检查表
   分析表的语法:
   analyze [local | no_write_to_binlog] table tab1_name [, ta1_name] ...
   用于分析和存储表的关键字分布
   分析结果可以使得系统得到更准确地统计信息,使得sql能够正确的执行计划。
   如果用户感觉实际执行计划并不是与预期的执行计划,执行一次分析表可能会解决问题。
   在分析期间,使用一个读取锁对表进行锁定,这对于MyISAM,BDB和InnoDb表有作用。对于MyISAM表,与使用myisamchk -a 相当
   例如:
   analyze table user;
mysql> analyze table user;
+------------+---------+----------+----------+
| Table      | Op      | Msg_type | Msg_text |
+------------+---------+----------+----------+
| mysql.user | analyze | status   | OK       |
+------------+---------+----------+----------+
1 row in set (0.05 sec)


   检查表的语法如下:
   check table tab1_name [,tab1_name] ... [option] .. option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED}
   作用是:检查一个或者多个表中是否有错误。他对MyISAM和InnoDB表有作用,对于MyISAM表,关键字统计数据被更新。例如:
  check table user;
mysql> check table user;
+------------+-------+----------+----------+
| Table      | Op    | Msg_type | Msg_text |
+------------+-------+----------+----------+
| mysql.user | check | status   | OK       |
+------------+-------+----------+----------+
1 row in set (0.00 sec)


  check table也可以检查视图是否有错误,例如:在视图定义中被引用的表不存在

3.2 定期优化表
    语法:
    optimize [local | no_write_to_binlog] table tab1_name [, tab1_name] ...
    适用范围:
    a、删除了表的一部分
    b、对含有可变长度行的表(varchar,blob,text列的表)进行了很多更改。
    这个命令可以将表中的空间碎片进行合并,并且可以消除由于删除或者更新造成的空间浪费。但是这个命令只对MyISAM,BDB和InnoDb表起作用
mysql> optimize table user;
+------------+----------+----------+----------+
| Table      | Op       | Msg_type | Msg_text |
+------------+----------+----------+----------+
| mysql.user | optimize | status   | OK       |
+------------+----------+----------+----------+
1 row in set (0.01 sec)


4 常用SQL的优化
  4.1 大批量插入数据
    当用load命令导入数据的时候,适当的设置可以提高导入的速度
    4.1.1 对于MyISAM存储引擎的表方法如下:
    alter table tab_name disable keys;
    load the data
    alter table tab_name enable keys;

    上面操作是打开或者关闭MyISAM表不是唯一索引的更新
    ps:导入非空数据表的时候,上面方法很有效,但是导入空表的时候,索引是数据导入完毕之后才去创建的,所以没有影响
    4.2.2 对InnoDB表的数据导入
     (1)InnoDB类型的表是按照主键的顺序来存储的,所以导入数据按照主键的顺序排列,可以有效的提高导入的效率
     (2)在导入数据之前,关闭唯一性校验,set unique_checks=0 ,在导入结束之后设置为 1 开启唯一性校验,可以提高导入效率
     (3)如果应用使用自动提交的方式,建议在导入数据的时候执行 set autocomment=0,关闭自动提交,导入结束之后再设置为1,打开自动提交

  4.2 优化insert语句
     (1)如果是从同一客户那里插入很多航,尽量使用多个值表的insert语句,这种方式将大大的缩短客户端与数据库之间的链接,关闭等资源的消耗,使得效率比分开执行的单个insert语句快
     例如:insert to test values(1,2),(1,3),(1,4)....
     (2)如果从不同的客户中杀入多行,能通过使用insert delayed语句得到更高的速度。delayed是让insert语句立马执行,四十数据都被放在内存的队列中,并没有真正的写入磁盘,这比每一条数据分别插入快得多。low_priority 刚好想法,是所有其他用户对表的读写完成后才进行插入
     (3)将索引文件和数据文件分在不同的磁盘上存放
     (4)如果进行批量插入可以增加 bulk_insert_buffer_size 变量值的方法来提高速度,但是这只能对MyIsAM表使用
     (5)当一个文本文件装载一个表时,使用 load file insert。这比通常的sql语句快20倍
4.3 优化group by语句
     如果查询包括group by但是用户想避免白须结果的小号,可以指定order by null禁止排序
   例如:
   select id, sum(money) from sale2 group by id order by null

4.4 优化order by语句
    可以使用索引来满足一个order by语句
    条件:
    where条件和order by使用相同的索引,并且order by的顺序和索引顺序相同,并且order by的字段都是升序或者降序
    比如: order by key1,key2
           where key1=123 order by key1 desc, key2 desc
           order by key1 desc, key2 desc

    但是以下情况不可以
       order by key1 asc, key2 desc 混合使用ASC和DESC
       where key2 = 1 , order by key1 查询的关键字和排序的不一样
       order by key1,key2 对不同的关键字使用排序

   
4.5 优化嵌套查询
     有些情况下,子查询可以被更加有效的join查询代替
     比如 select * from a where b_id not in(select id from b) 
     换成 select * from a left join b on a.b_id = b.id where a.b_id is not null


  4.6 优化OR条件
      or的每一个条件都使用索引
      但是如果or的几个条件正好是复合索引的元素,则不能起到加速的效果
   4.7 使用SQL提示
      在sql中加入一些人为的提示来达到优化操作的目的
      例如:
      select sql_buffer_results * from
      这个语句将强行MySql生成一个临时的结果集,只要临时结果集生成之后,所有表上的锁都会被释放。
      这能解决遇到表锁问题时,或者要花长时间将结果传给客户端时有所帮助,因为这样可以尽快的释放资源

      (1)use index
      在查询语句中表名的后面,添加use index来提供希望mysql去参考的索引列表,就可以让mysql不再考虑其他可用的索引
      select * from a use index(ind_a_id) where id = 1

      (2)ignore index
      如果用户只是单纯的想让mysql忽略一个多个索引,则可以使用ignore index作为hint
       select * from a ignore index(ind_a_id) where id = 1

      (3)force index
      强制MySQL使用一个特定的索引,可在查询中使用


      
分享到:
评论

相关推荐

    读书笔记:深入浅出MySQL 数据库开发 优化与管理维护 第2版 唐汉明源码.zip

    读书笔记:深入浅出MySQL 数据库开发 优化与管理维护 第2版 唐汉明源码

    深入浅出MySQL-读书笔记byCZF

    在MySQL数据库的使用过程中,有多个关键的知识点需要掌握,以保障数据库的高效稳定运行。 首先,MySQL的安装与配置是基础中的基础,这包括了解MySQL的性能优势,以及在Linux环境下如何启动、重启和关闭MySQL服务。...

    MySQL数据库深入浅出学习笔记

    最详细!! 最简单!!! 最通俗易懂的mysql数据库的学习笔记, 零基础新手小白必备, 少走弯路

    MySQL数据库课堂笔记.xmind

    深入浅出mysql数据库。内容如下: 1、什么是数据库 2、Mysql相关操作 3、数据库相关操作 4、数据表相关操作 5、mysql中的数据类型 6、mysql数据引擎 7、mysql数据库操作:增删改查、多表联查、聚合函数等用法...

    MySQL大佬姜承尧49完整课程笔记,进阶涨薪必看,内含MySQL配置文件

    姜承尧作为知名的MySQL专家,他的课程深入浅出地讲解了MySQL的高级概念和技术,帮助DBA(数据库管理员)和开发者提升技能,从而在职场上实现涨薪进阶。这份笔记包含了丰富的知识点,以下是对这些内容的详细阐述: 1...

    数据库笔记

    **MySQL数据库笔记** MySQL是一种广泛使用的开源关系型数据库管理系统(RDBMS),它以其高效、稳定和易用性在全球范围内受到青睐。这份“数据库笔记”深入浅出地介绍了MySQL的各种核心概念和技术,旨在帮助读者全面...

    MySQL入门到高级-康师傅版.zip

    尚硅谷教育机构的宋红康老师倾力打造,通过一系列深入浅出的讲解,使学习者能够全面了解和掌握MySQL的各个方面。 首先,我们要了解MySQL的基本概念。MySQL是一种开源、免费的SQL数据库,由Oracle公司维护。它以高效...

    Mysql+笔记+入门教程+MySQL详细安装图解

    本教程将基于提供的“Mysql+笔记+入门教程+MySQL详细安装图解”资源,深入浅出地介绍MySQL的基础知识、安装过程以及一些实用的开发技巧。 首先,让我们来了解MySQL的基础概念。MySQL基于SQL(结构化查询语言)标准...

    燕十八刘道成Mysql数据库课堂笔记.zip

    MySQL数据库是世界上最受欢迎的开源关系型数据库之一,广泛应用于各种规模的企业、...这份笔记深入浅出地讲解了MySQL数据库的核心知识,适合初学者和有一定经验的开发者作为参考,帮助读者逐步提升在MySQL领域的技能。

    Mysql学习笔记.pdf

    推荐的书籍包括《MySQL必知必会》和《MySQL深入浅出》,这两本书可以帮助初学者快速理解和运用MySQL的基本功能。对于进阶学习,可以参考《MySQL排错指南》和《高性能MySQL》。官方文档是学习的重要资源,可以在...

    MySQL学习笔记_个人学习用

    本笔记主要基于《深入浅出MySQL数据库开发、优化与管理维护》一书,旨在帮助个人学习MySQL的基础知识和开发技巧。 MySQL的学习首先从理解数据库的基本概念开始。事务性数据库是指能够支持事务处理的数据库,比如...

    《MySQL必知必会》阅读笔记1

    《MySQL必知必会》是一本深入浅出的MySQL数据库学习指南,涵盖了MySQL的基础知识、操作技巧以及实际应用。在阅读笔记中,我们将探讨以下几个关键知识点: 1. 数据库概念:MySQL是一种关系型数据库管理系统(RDBMS)...

    鲁班学院MySQL课堂笔记(B+树索引,事务,锁)

    鲁班学院的这份课堂笔记深入浅出地探讨了MySQL中的核心概念:B+树索引、事务处理以及锁定机制。 一、InnoDB行格式、数据页结构以及索引底层原理分析 InnoDB是MySQL中最常用的存储引擎,它支持事务处理和行级锁定。...

    mysql书籍学习笔记.rar

    《MySQL数据库应用从入门到精通》是一本深入浅出的MySQL学习资料,涵盖了数据库的基础概念、安装配置、SQL语句的使用以及高级特性的探讨。通过这本书的学习,读者可以了解到MySQL在实际工作中的广泛应用和重要性。...

    学习mysql基本命令笔记....zip

    本笔记将深入浅出地介绍MySQL的基本命令,帮助初学者快速掌握数据库操作。 一、安装与启动MySQL 在安装MySQL后,通常可以通过系统服务或命令行来启动和停止数据库服务。在Windows上,可以使用`net start MySQL`启动...

    《MYSQL必知必会》读书笔记

    《MYSQL必知必会》是一本深入浅出介绍MySQL的书籍,旨在帮助读者掌握MySQL的基础知识和高级特性。以下是对这本书中核心知识点的详细解析: 1. **SQL语言基础**: SQL(Structured Query Language)是用于管理关系...

    学习《MySQL 45讲》的笔记,在小林coding《图解MySQL》上添加一些笔记.zip

    《MySQL 45讲》是一本深入浅出的教程,结合小林coding的《图解MySQL》的解析,可以帮助我们更好地理解和运用这个广泛使用的数据库系统。这份笔记集合了两本书中的精华,并可能加入了作者kwan1117的个人见解和实践...

    mysql菜鸟进阶电子书

    通过深入浅出的讲解,读者可以学习到如何设计高效的数据模型,优化SQL查询,以及进行数据库的安全管理和备份恢复。此外,本书还会介绍如何在实际项目中应用MySQL,比如在Web开发中的集成和性能调优,从而提升读者的...

    MySQL笔记(5)深入浅出索引(下)

    在MySQL数据库中,索引是提高查询效率的关键因素。在给定的例子中,表`T`有一个主键`ID`和一个对`k`字段的索引。当我们执行`SELECT * FROM T WHERE k BETWEEN 3 AND 5`时,查询会通过`k`的索引树找到满足条件的记录...

Global site tag (gtag.js) - Google Analytics