zoukankan      html  css  js  c++  java
  • 高性能MySql学习笔记附录

    A. MySQL分支与变种

    Percona Server

    • Percona Server 是个与 MySQL 向后兼容的替代品,任何运行在 MySQL 上的都可以运行在 Percona Server 上。
    • Percona Server 包括 Percona XtraDB 存储引擎,即改进版本的 InnoDB,这同样是个向后兼容的替代品。

    MariaDB

    Drizzle

    • Drizzle 是真正的 MySQL 的分支,而非只是个变种或增强版本。它并不与 MySQL 兼容。

    B. MySQL服务器状态

    系统变量

    • MySQL 通过 SHOW VARIABLES SQL命令展示系统变量。

    SHOW STATUS

    • SHOW STATUS命令会显示每个服务器变量的名字和值。这些变量是只读的。如果使用 SQL 命令,可以使用 LIKE 或 WHERE 来限制结果。可以从 INFORMATION_SCHEMA.GLOBAL_STATUS 和 INFORMATION_SCHEMA.SESSION_STATUS 表中查询。

    • 现在SHOW STATUS默认展示会话变量,如果查看全局变量,则需要运行SHOW GLOBAL STATUS

    • 线程和连接统计。这些变量用来跟踪尝试的连接、退出的连接、网络流量和线程统计等。

    • 二进制日志状态。Binlog_cache_use和 Binlog_cache_disk_use状态变量显示了在二进制日志缓存中有多少事务被存储过,以及多少事务因超过二进制日志缓存而必须存储到一个临时文件中。

    • 命令计数器。Com_*变量统计了每种类型的 SQL 或 C API 命令发起过的次数。

    • 临时文件和表

    • 句柄操作。句柄 API 是 MySQL 和存储引擎之间的接口。Handle_* 变量用于统计句柄操作。

    • MyISAM 键缓冲。 Key_*变量包含度量值和关于 MyISAM 键缓冲的计数。

    • 文件描述符。对于 MyISAM 存储引擎,Open_*变量揭示 MySQL 每隔多久打开每个表的.frm、.MYI 和.MYD 文件。InnoDB 保持所有的数据在表空间文件中,所以对于 InnoDB这些变量并不准确。

    • 查询缓存。查询 Qcache_*状态变量可以检查查询缓存。

    • SELECT 类型。Select_*变量是特定类型的 SELECT 查询的计数器。它们展示各种查询计划的 SELECT 查询比率。

    • 排序。当 MySQL 不能使用索引获取预先排序的行,则必须使用文件排序,这会增加 Sort_*状态变量。

    • 表锁。Table_locks_immediate 和 Table_locks_waited 变量展示有多少锁被立即授权,有多少锁需要等待。

    SHOW ENGINE INNODB STATUS

    • InnoDB 存储引擎在SHOW ENGINE INNODB STATUS输出中,它的输出是单独的一个字符串,分为很多小段。
    • SEMAPHORES。包含了两种数据:事件计数器、以及可选的当前等待线程的列表。如果有高并发的工作负载,则需要关注该端。
    • LATEST FOREIGN KEY ERROR。展示服务器最新的外键错误。
    • LATEST DETECTED DEADLOCK。展示服务器内最新的死锁信息。
    • TRANSACTIONS。包含关于 InnoDB 事务的总结信息,紧随其后是当前活跃事务列表。
    • FILE I/O。FILE IO 部分显示的是 IO 辅助线程的状态,还有性能计数器的状态。
    • INSERT BUFFER AND ADAPTIVE HASH INDEX。显示关于插入缓存和自适应哈希索引的状态。
    • LOG。显示关于 InnoDB 事务日志(重做日志)子系统的统计。
    • BUFFER POOL AND MEMORY。显示关于 InnoDB 缓冲池机器如何使用内存的统计。
    • ROW OPERATIONS

    SHOW PROCESSLIST

    • 进程列表是当前连接到 MySQL 的连接或线程的清单。SHOW PROCESSLIST 列出了这些线程,以及每个线程的状态信息。Command 和 State 列真正表明了线程的状态。

    SHOW ENGINE INNODB MUTEX

    • 改命令返回 InnoDB 互斥体的详细信息,每个互斥体都保护着代码中一个临界区。

    复制状态

    • MySQL 有几个命令用以监测复制。在主库上执行SHOW MASTER STATUS 可显示主库的复制状态和配置。输出包含了主库当前的二进制日志位置。通过SHOW BINARY LOGS可以获取到二进制日志的列表。通过SHOW BINLOG EVENTS可以查看二进制日志中的事件。在备库上执行 SHOW SLAVE STATUS查看复制的状态和配置。

    INFORMATION_SCHEMA

    • INFORMATION_SCHEMA 库是一个 SQL 标准中定义的系统视图的集合。能够以标准的 SQL 来进行查询。

    Performance Schema

    • Performance Schema是 MySQL 增强仪表的新的汇总处。默认情况下,Performance Schema是禁用的,需要打开并且使其在一个想要手机的特定的仅表点启用。

    C. 大文件传输

    一个简单的示例

    • 在server1的源服务器,将文件进行压缩,并使用scp方法复制到server2
    $ gzip -c /backup/mydb/mytable.MYD > mytable.MYD.gz
    $ scp mytable.MYD.gz root@server2:/var/lib/mysql/mydb/
    
    • 在server2执行如下命令,进行解压
    $ gunzip /var/lib/mysql/mydb/mytable.MYD.gz
    
    • 这个方法效率不高,因为在server1上gzip需要读写,scp在server1上读在server2上写,gunzip在server2上既要读又要写。

    一步到位的方法

    • 下面这个方法将压缩、复制文件和在传输的另一端解压缩文件全部放在一个步骤里完成。这个方法只需要在server1读,在server2上写。
    $ gzip -c /backup/mydb/mytable.MYD | ssh root@server2 "gunzip -c - > /var/lib/mysql/mydb/mytable.MYD" 
    

    避免加密的系统开销

    • SSH 部署跨网传输数据的最快方法,因为它增加了加解密的系统开销。如果不需要加密,可以使用netcat把“裸数据”进行跨网传输。

    其他选项

    • 另一个选项是rsync。rsync易于在源和目标直接做镜像,并且还可以断点续传。但是,如果它的二进制差异算法无法被很好的发挥时,它不太会得到很好应用。

    D. EXPLAIN

    调用 EXPLAIN

    • 在 SELECT 关键字前增加 EXPLAIN 这个词,MySQL 在执行查询时,这个标记会使其返回关于在执行计划中的每一步的信息,而不是执行它。
    • EXPLAIN 语句并不总是不执行查询,如果在 FROM 子句中包含子查询,那 MySQL 实际会执行子查询。
    • EXPLAIN 只是一个近似结果,有时其结果与真相相差甚远。

    EXPLAIN 中的列

    • id 列。id 列包含一个编号,标识 SELECT 所属的行。如果语句中没有子查询或联合,那么只会有唯一的 SELECT,于是每一行在这个列中都将显示一个1。否则,内层的 SELECT 语句一般会顺序编号。

    • select_type 列。这一列展示了对应行是简单查询还是复杂查询,如果是复杂查询,那么是三种复杂类型中的哪一种。SIMPLE值意味着查询不包括子查询和 UNION。如果查询有任何复杂的子部分,则最外层部分标记为 PRIMARY。其他部分标记如下:

      • SUBQUERY。包含在 SELECT 列表中子查询的 SELECT。(不在 FROM 子句中)。
      • DERIVED。包含在 FROM 子句的子查询中的 SELECT。
      • UNION。在 UNION 中的第二个和随后的 SELECT 被标记为 UNION。
      • UNION RESULT。用来从 UNION 的匿名临时表中检索结果的 SELECT 被标记为 UNION RESULT。
    • table 列。展示对应行正在访问哪个表。

    • type 列。代表访问类型,也就是 MySQL 决定如何查找表中的行。如下为重要的访问方法,依次从差到优。

      • ALL。俗称全表扫描,代表 MySQL 必须扫描整张表来查询数据。
      • index。这个同样是全部扫描,只不过扫描表时按索引顺序进行,而不是行顺序。它的主要优点是避免了排序,缺点是要承担按索引排序读取整个表的开销,因为这往往是随机读取。
      • range。范围扫描就是一个有限制的索引扫描。这比全索引扫描好一些,因为不用遍历全部索引。常见的范围扫描是带有 BETWEEN 或在 WHERE 子句中带有比较的查询。
      • ref。这是一种索引访问,返回所有匹配某个单个值的行,当然也可能有多个符合条件的行。
      • eq_ref。这也是一种索引访问,相比 ref,MySQL 确定最多只返回一条符合条件的记录。
      • const,system。当 MySQL 能对查询的某部分优化转化为常量时,则使用此种访问类型。
      • NULL。 这种访问方式意为着 MySQL 能够在优化阶段分解查询语句,在执行阶段甚至用不着再访问表或者索引。
    • possible_keys 列。这一列显示了查询可以使用哪些索引,这是基于查询访问的列和使用的比较操作符来判断的,这里出现的索引不代表 MySQL 最终会选择他们。

    • key 列。这一列展示 MySQL 最终选择了哪个索引来优化对该表的访问。如果该索引没有出现在 possible_keys 列中,那么 MySQL 选用它是由于另外的原因——例如,它可能选择了一个覆盖索引,哪怕没有 WHERE 子句。

    • key_len列。该列显示了 MySQL 在索引里使用的字节数。如果 MySQL 正在使用的只是索引里的某些列,可以根据这个值进行推算,比如一个联合索引,但是只使用了其最左侧列的情况。

    • ref列。这一列展示了之前的表在 key 列记录的索引中查找值所用的列或常量。

    • rows 列。这一列是 MySQL 估计为了找到所需的行而要读取的行数。它不是 MySQL 认为最终要从表里读取出来的行数,而是 MySQL 为了查询而必须扫描的行数。

    • filtered列。它显示的是针对表里符合某个条件(WHERE 子句或联接条件)的记录数的百分比所做的一个悲观估算,优化器只有在使用 ALL、index、range、和 index_merge 访问方法时才会使用这一估算。

    • Extra 列。这一列显示不适合在其他列显示的额外信息。常见的重要的值如下:

      • Using index。表示 MySQL 将使用覆盖索引,以避免访问表。不要把覆盖索引和 index 访问类型弄混了。
      • Using where。这意味着 MySQL 服务器将在存储引擎检索行后再进行过滤。又是 Using where 的出现就是一个暗示:查询可受益于不同的索引。
      • Using temporary。代表 MySQL 在对查询结果排序时会使用一个临时表。
      • Using filesort。这意味着 MySQL 会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。

    MySQL5.6中的改进

    • MySQL 5.6中包括一个对 EXPLAIN 的重要改进:能对类似 UPDATE、INSERT 等的查询进行解释。

    E. 锁的调试

    服务器级别的锁等待

    • 锁等待可能发生在服务器级别或存储引擎级别。服务器级别的锁有表锁、全局锁、命名锁、字符锁等类型。
    • 表锁
      • 表锁可以是显式的,也可以是隐式的。显示的锁用 LOCK TABLES 创建。可以执行如下命令,在 sakila.film 上获取一个显式的锁:LOCK TABLES sakila.film READ;
      • 如果在另一个会话中也获取这个表的锁,查询将被挂起并且不会执行:LOCK TABLES sakila.film WRITE;
      • 使用命令SHOW PROCESSLIST;可以看到等待线程的状态是 Locked。
      • 服务器在查询过程中也会隐式地锁住表。一个长时间的查询即可将表锁住:SELECT SLEEP(30) FROM sakila.film LIMIT 1;当这个查询运行时,尝试再次锁住 film 表将会因为隐式锁而挂起。
      • 隐式锁和显式锁会阻塞,隐式锁也会相互阻塞。
    • 全局读锁
      • MySQL 服务器实现了一个全局读锁,可以如下获取该锁:FLUSH TABLES WITH READ LOCK;
      • 如果此时在另一个会话中尝试获取表锁,将会被挂起。而等待线程在 SHOW PROCESSLIST 中的状态将会是 Waiting for release of readlock,代表查询在等待一个全局读锁而不是表级锁。
    • 命名锁
      • 命名锁是一种表锁:服务器在重命名或删除一个表时创建。命名锁与普通的表锁相冲突,无论是显式还是隐式的。
    • 用户锁
      • 在服务器中实现的最后一种锁是用户锁,它是一个命名互斥量,需要指定锁的名称字符串,以及等待超时秒数。SELECT GET_LOCK('my lock', 100);
      • 如果另一个线程尝试锁相同字符串,它将被挂起直到超时。

    InnoDB 的锁等待

    • InnoDB 在SHOW INNODB STATUS的输出中显示了一些锁信息。也可以通过查询 INFORMATION_SCHEMA 表的方式来显露 InnoDB 的事务和锁。
  • 相关阅读:
    oracle中Blob和Clob类型的区别
    为什么要分库分表
    Enable file editing in Visual Studio's debug mode
    SQL Server Dead Lock Log
    Debug .NET Framework Source
    SQL Server text field里面有换行符的时候copy到excel数据会散乱
    诊断和修复Web测试记录器(Web Test Recorder)问题
    Can't load Microsoft.ReportViewer.ProcessingObjectModel.dll
    'telnet' is not recognized as an internal or external command
    Linq to XML
  • 原文地址:https://www.cnblogs.com/lianggx6/p/15612009.html
Copyright © 2011-2022 走看看