MySQL:索引优化分析


本文通过学习尚硅谷Mysql索引视频整理得出


简介

概述

  • 在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构就是索引。
  • 官方定义:索引是帮助Mysql高效获取数据的数据结构
  • 索引的目的在于提高查询效率,可以类比字典。
  • 对已排序的快速查找数据结构。索引:排序、查找。
  • 一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在硬盘上。我们平常如果没有特别指明,索引都是指B树索引(并不一定是二叉树),其中聚集索引、复合索引、前缀索引、唯一索引默认都是使用B+索引。除了B+树索引外,还有哈希索引等。
  • 优势:
    (1)建索引,提高了数据检索的效率,降低了数据库的IO成本。
    (2)通过索引对数据进行排序,降低数据排序的成本,降低了CPU的消耗。
  • 劣势:
    (1)实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以使用索引列需要占用额外的空间。
    (2)虽然索引提高了查询速度,但会降低更新表的速度。当对表进行写操作(insert、update、delete)时,mysql不仅要更新表中的数据,还要更新索引列中因这次写操作带来的键值变化的索引信息。
    (3)索引的建立需要花时间研究建立最优秀的索引。

mysql索引分类

  • 单值索引:一个索引只包含单个列,一个表可以有多个单列索引(一般一个表的索引不要超过五个)。
  • 唯一索引:索引列的值必须唯一,但允许有空值。
  • 复合索引:一个索引包含多个列。一般复合索引优于单值索引,在高并发下倾向创建复合索引。

基本语法

  • 创建索引:CREATE [UNIQUE] INDEX index_name ON table_name(column_name(length));
    ALTER table_nameADD [UNIQUE] INDEX [index_name] ON (colunmn_name(length));
  • 删除索引:DROP INDEX [index_name] ON table_name
  • 查询索引:SHOW INDEX FROM table_name;

添加数据库表的索引:

  • 添加主键:ALTER TABLE tb_name ADD PRIMARY KEY (column_list);
  • 创建唯一索引:ALTER TABLE tb_name ADD UNIQUE index_name (column_list);
  • 添加普通索引:ALTER TABLE tb_name ADD INDEX index_name (column_list);
  • 全文索引:ALTER TABLE tb_name ADD FULLTEXT index_name (column_list);

mysql索引结构

B+Tree索引

  • mysql默认使用B+树索引
  • 对于一颗B+Tree树来说,非叶子节点不存储真实数据,只存储指引搜索方向的数据项。真实数据存在于叶子节点中。
  • 查找一层,即发生一次IO,当查找到叶子节点的时候,内存通过二分查找查找真实值的位置。因此我们BTree树的高度越低越好。实际上,3层的b+树可以表示上百万条数据,即在上百万的数据中进行查找只需要三次IO(加载数据到内存也会发生一次IO),性能的提高很大,如果没有索引,每个数据项都要发生一次IO,那么总共需要百万次IO,成本非常高。

Hash索引:不支持模糊查询
full-text全文索引
R-Tree索引

是否创建索引的选择

字段需要创建索引的情况:

  1. 主键自动建立唯一索引
  2. 频繁作为查询条件的字段应该创建索引
  3. 查询中与其它表关联的字段,外键关系建立索引
  4. 频繁更新的字段不适合作为索引,因为会降低更新速度(mysql不仅要更新表中的数据,还要更新索引列中因这次写操作带来的键值变化的索引信息)
  5. Where条件里用不到的字段不创建索引
  6. 单键/组合索引的选择问题
  7. 查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度(索引排序的规则,与查询是order by是否统一)
  8. 查询中统计或者分组字段(group by分组的前提是已经排序了)

不要创建索引的情况:

  1. 表记录太少
  2. 经常增删改的表(不仅要更新原表,还要更新索引表)
  3. 数据重复且分布平均的表字段,如果某个数据列包含许多重复字段,那么为它建索引就没有太大的实际效果。一个索引的选择性(索引字段不同的值/表中总记录数)越接近于1,这个索引的效率就越高。

性能分析

MySQL Query Optimizer

  • Mysql中有专门负责优化SELECT语句的优化器模块,就是“MySQL Query Optimizer”,它的主要功能是通过计算分析系统中收集到的统计信息,为客户端请求的Query提供他认为最优的执行计划(不一定是DBA认为最优的)
  • 当客户端向Mysql请求一条Query,命令解析器模块完成请求分类,确认是SELECT语句后转发给MySQL Query Optimizer时,MySQL Query Optimizer首先会对整条Query进行优化:处理掉一些常量表达式的预算,直接换算成常量值。并对Query中的查询条件进行简化和转换,如去掉一些无用或显而易见的条件,结构调整等。然后分析Query中的Hint信息,看显示Hint信息是否可以完全确定该Query的执行计划。如果没有Hint或Hint信息还不足以完全确定执行计划,则会读取所涉及对象的统计信息,根据Query进行写相应的计算分析,然后再得出最后的执行计划。

MySQL常见瓶颈

  1. CPU:CPU饱和的时候一般发生在数据装入内存或从磁盘上读取数据时。
  2. IO:磁盘I/O瓶颈发生在装入数据远大于内存容量的时候。
  3. 服务器硬件的性能瓶颈。

Explain

概述

  • 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理一条SQL语句。从中可以分析该查询语句或表结构的性能瓶颈。

作用

  1. 能够查看到多个表最终的读取和加载顺序(id)
  2. 数据读取操作的操作类型(select_type)
  3. 哪些索引可以使用(possible_keys)
  4. 哪些索引被实际使用(key)
  5. 表之间的引用(ref)
  6. 每张表有多少行被优化器查询(rows)

使用

  • 语法:EXPLAIN + SQL 语句

  • 执行计划包含的信息:id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra。其中,关键的衡量指标有:id、type、key、rows、Extra。

    • id:select查询的序列号,包含一组数字。当查询语句涉及select子句或多个表的时候,该id值表示执行select子句或操作表的顺序。id值有三种情况:1️⃣ id相同:执行顺序根据表id对应的table名由上至下。2️⃣ id不同:如果是子查询,id的序号会比父查询递增1,id值越大优先级越高,越先被执行。 3️⃣ id有相同也有不相同:先执行id值大的,如果遇到id值相等,则对于该id值一样的操作从上往下顺序执行。
    • select_type:主要用于区别查询的类型,有六种类型。
    1. SIMPLE:简单的select查询,不包含子查询或者UNION
    2. PRIMARY:查询中若包含任何复杂的子查询,最外层(最后加载的)查询会被标记为PRIMARY。
    3. SUBQUERY:在SLECT或WHERE列表中包含的子查询,就会被标记为SUBQUERY。
    4. DERIVED:在FROM列表中包含的子查询会被标记为DERIVED(衍生),MySQL会递归这些子查询,并将结果放在DERIVED的临时表里。
    5. UNION:若第二个SELECT出现在UNION之后,则被标记为UNION。若UNION包含在FROM子句的子查询中,外层SELECT将被标记为:DERIVED。
    6. UNION RESULT:从UNION表获取的结果。
    • table:显示这一行的数据是关于哪张表的。若table值为<derived2>,则表示该表是id为2的子查询衍生的临时表,而id为2的select_type为DERIVED。

    • type:访问类型,显示查询使用了何种类型。常见的值如右边几种值:ALL、index、range、ref、eq_ref、const,system、NULL。从最好到最差的排序依次是:system > const > eq_ref > ref > range > index > ALL。一般来说得保证查询至少达到range级别,最好能达到ref。

    1. system:表只有一行记录(等于系统表),这是const类型的特例,平时不会出现,可以忽略不计。
    2. const:表示通过索引一次就找到了。常用于比较primary key或者unique索引,因为只匹配一条数据,所以很快。如果将主键置于where列表中,MySQL就能将该查询转换为一个常量。
    3. eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描。
    4. ref:非唯一性索引扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问,会返回所有匹配某个单独值的行,然而可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体。
    5. range:只检索给定范围的行,使用一个索引(即定义范围的属性列)来选择行,这时候key列显示使用了哪个索引。一般是在where语句中出现了between···and···、<、>、in等查询,这种范围扫描索引比全表扫描要好。
    6. index:Full Index Scan。select的属性列全都在索引里有包含。index与ALL区别为index类型只遍历索引树。通常比ALL快,因为索引文件通常比数据文件小。即虽然all和index都是读全表,但index是从索引中读取的,而all是从硬盘中读取的。
    7. ALL:Full Table Scan。最差,全表扫描。如果数据量大,必须优化。
    • possible_keys:显示可能应用在这张表中的索引,值可能有一个或多个。理论值。查询涉及到的字段若存在索引,则该索引将被列出,但不一定被查询实际使用

    • key实际使用的索引。如果为NULL,则没有使用索引(没索引,或有但没有用到,即索引失效)。有可能出现在possible_keys中没有出现的索引。查询中若使用了覆盖索引,则该索引仅出现在key列表中。

    • key_len:表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精度性的情况下,长度越短越好。key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的。

    • ref:显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值。值可能为库名.表名.字段,const(常量),NULL(空)。

    • rows:根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数。

    • Extra:包含不适合在其他列中显示但十分重要的额外信息。

    1. Using filesort(不好):说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL中无法利用索引完成的排序操作称为“文件内排序”。出现这种情况比较危险,如果可以,尽快优化(想办法让mysql使用我们的索引,而不是文件内排序)。
    2. Using temporary(不好):使用了临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于排序order by和分组查询group by。非常危险,增加系统负担。
    3. Using index(好):表示相应的select操作中使用了覆盖索引,避免访问了表的数据行,效率好。如果同时出现using where,表明索引被用来执行索引键值的查找;如果没有同时出现using where,表明索引用来读取数据而非执行查找动作。
    4. Using where:表明使用了where过滤。
    5. Using join buffer:使用了连接缓存。
    6. impossible where:提示where的值总是false,不能用来获取任何元组。
    7. select table optimized away:在没有group by子句的情况下,基于索引优化MIN/MAX操作或者对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。少用。
    8. distinct:优化distinct操作,在找到第一匹配的元组后即停止找同样值的动作。少用。

覆盖索引:有时候又称为索引覆盖。有两种理解方式:

  • 理解方式一:select的数据列只用从索引中就能取得,不必读取数据行,MySQL可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件,换句话说查询列要被所建的索引覆盖。
  • 理解方式二:索引是高效找到行的一个方法,但是一般数据库也能使用索引找到一个列的数据,因此它不必读取整个行。毕竟索引叶子节点存储了它们索引的数据;当能通过读取索引就可以得到想要的数据,那就不需要读取行了。一个索引包含了/覆盖了满足查询结果的数据就叫做覆盖索引。
  • 如果要使用覆盖索引,注意select列表中只取出需要的列,不可“select *”。因为如果将所有字段一起做索引会导致索引文件过大,查询性能下降。

注意

  • 如果为range类型查询字段及其他字段建立复合索引,那么range类型后面的索引无效,type会变成range类型,且还是会出现Using filesort的情况。
  • 左连接的时候,左表全都有,右表不一定有,所以我们应该确定右表哪些有,因此索引应该建在右表。反之,右连接应该建立索引在左表。
  • 尽可能减少Join语句中的循环总次数;永远用小结果驱动大的结果集。保证Join语句中被驱动表上的Join条件字段已被索引。当无法保证被驱动表的Join条件字段被索引且内存资源充足时,可以增大JoinBuffer的设置。

索引失效

  1. 全值匹配最好:即索引的全部都匹配上了。
  2. 最佳左前缀法则:如果索引了多列,要遵守最左前缀法则。指的是查询从索引(复合索引)的最左前列开始并且不跳过索引中的列。如果只有左前列,也可以匹配上。
  3. 不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描。
  4. 存储引擎不能使用索引中范围条件右边的列,即范围右边的条件全失效。
  5. 尽量使用覆盖索引(只访问索引的查询(索引列与查询列一致)),减少使用select*。
  6. mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描。
  7. is null(type=NULL),is not null(type=ALL)也无法使用索引。
  8. like以通配符开头(’%abc…’)mysql索引失效会变成全表扫描的操作。(可以使用覆盖索引解决这个问题)
  9. 字符串(varchar)不加单引号会导致索引失效。(可以查询出来,但mysql会隐式自动类型转换,导致索引失效,与第三点一致)
  10. 少用or,用它来连接时会索引失效。

口诀
全值匹配我最爱,最左前缀要遵守;
带头大哥不能死,中间兄弟不能断;
索引列上少计算,范围之后全失效;
Like百分写最右,覆盖索引不写星;
不等非空还有or,索引失效要少用;
VAR引号不可丢,SQL高级也不难!

使用建议

  • 对于单键索引,尽量选择针对当前query过滤性更好的索引。
  • 在选择组合索引的时候,当前query中过滤性最好的字段在索引字段顺序中,位置越靠左越好。
  • 在选择组合索引的时候,尽量选择可以能够包含当前query中的where子句中更多字段的索引。
  • 尽可能通过分析统计信息和调整query的写法来达到选择合适索引的目的。

查询优化

IN 与 EXISTS

  • 永远使用小表来驱动大表
  • in与exists的使用:
    SELECT ··· FROM table_name WHERE IN/EXISTS (子查询)
    ①使用IN的时候,是先进行子查询,然后将子查询的结果作为条件,进行父查询。
    ②使用EXISTS的时候,先进行父查询,将查询结果放到子查询中做条件验证,根据验证的结果(TRUE/FALSE)来决定父查询的结果是否要保留。
    ③EXISTS只会返回TUR/FALSE,子查询中SELECT的字段会被忽略,因此写 SELECT * 或 SELECT 1等其他都是没有区别的。
    ④因此,当父查询用到的表数据小于子查询表的数据时,使用EXISTS更优;当子查询表的数据集小于父查询表的数据集时,使用IN更优。

ORDER BY

  • ORDER BY 子句,尽量使用index方式排序(有序索引排序),避免Using filesort(文件排序)的排序方式。
    ORDER BY 默认使用升序排序,因此使用到了索引,但是排序不一致的话也会使用Using filesort。
    如果WHERE使用索引的最左前缀定义为常量,则ORDER BY能使用索引。
    满足以下两种情况,会使用index方式排序:(最佳左前缀原则)
    ①ORDER BY 语句使用索引最左前列的顺序排序。
    ②使用WHERE子句与ORDER BY子句条件列组合满足索引最左前列。
  • 尽可能在索引列上完成排序操作,遵照索引的最佳左前缀原则
  • 如果不在索引列上,filesort有两种算法:双路排序、单路排序
    1. 双路排序:会进行两次扫描磁盘,最终得到数据。读取行指针和orderby列,对它们进行排序,然后扫描已经排序好的列表,按照列表中的值重新从列表中读取对应的数据输出。在Mysql 4.1之前使用,因为I/O很耗时,而双路排序要进行两次磁盘扫描,因此4.1之后出现了改进算法单路排序。
    2. 单路排序:从磁盘读取查询需要的所有列,按照ORDER BY列在buffer对它们进行排序,然后扫描排序好的列表进行输出。效率更快,避免了第二次查询,并且把随机I/O变成了顺序I/O,但它把每一行都保存在内存中了,所以会使用更多的空间。
      单路排序有问题:单路排序是把所有字段取出,因此有可能出现取出数据的总大小超过了sort_buffer的容量,导致每次只能取规定大小的数据进行排序(多路合并),因此会出现排序完后再取规定大小,直到全部取完排序,因此可能会造成比2次还多的I/O,得不偿失。
    • 使用ORDER BY的时候尽量不要使用SELECT *,可能会超过sort_buffer容量,造成多次I/O。
      在这里插入图片描述

GROUP BY

  • 先排序后分组,遵循索引建的最佳左前缀。
  • 当无法使用索引列的时候,要增大max_length_for_sort_data参数的设置和增大sort_buffer_size参数的设置。
  • WHERE高于HAVING。如果能在WHERE限定的条件,就不要在HAVING中限定。

查询截取分析

慢查询日志

  • 是一种日志记录,用来记录在Mysql中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,会被记录到慢查询日志中,支持将日志记录写入文件。默认值是10s,意思是运行10s以上的语句。我们可以自己设置long_query_time值,收集超过该值的sql,然后就可以使用EXPLAIN进行全面分析、优化sql。
  • 默认Mysql没有开启,需要手动开启。一般只有调优的时候会开启,因为开启会消耗一定的性能。
    1. 查看是否开启及日志存放路径:SHOW VARIABLES LIKE '%slow_query_log%'
    2. 开启:set global slow_query_log=1;(使用该命令只对当前数据库生效,重启后会失效)
    3. 如果要永久生效,必须修改配置文件my.cnf,但开启该功能一般只在调优的时候,没必要永久生效。
  • 超时参数设置
    1. 查看超时时间:SHOW VARIABLES LIKE '%long_query_time%';
    2. 设置时间:set global long_query_time=n;(其中n为数值,单位是秒),修改后需要重新连接或者重开会话才能看到修改值,或者使用show global variables like 'long_query_time'';查看本地值。
    3. 查询超时sql数量:show global status like '%slow_queries%';
  • mysqldumpslow工具
    有以下几个常用的参数:
    1. s :表示按照何种方式排序
    2. c :访问次数
    3. l :锁定时间
    4. r :返回记录
    5. t :查询时间
    6. al :平均锁定时间
    7. ar :平均返回记录数
    8. at :平均查询时间
    9. t :即为返回前面多少条的数据
    10. g :后边搭配一个正则匹配模式,大小写不敏感

常用的命令:

  1. 得到返回记录集最多的10个SQL:mysqldumpslow -s -r -t 10 慢sql日志文件路径
  2. 得到访问次数最多的10个SQL:mysqldumpslow -s -c -t 10 慢sql日志文件路径
  3. 得到按照时间排序的前10条里面含有左连接的查询语句:mysqldumpslow -s t -t 10 -g "left join" 慢sql日志文件路径
  • 建议在使用命令的时候结合 | more 使用,否则可能出现爆屏。使用如:mysqldumpslow -s -r -t 10 慢sql日志文件路径 | more

show profile

  • 是mysql提供可以用来分析当前会话中语句执行的资源消耗情况,可以用于SQL的调优的测量。
  • 默认情况下,参数处于关闭状态,并保存最近15次的运行结果。

分析步骤

  1. 查看当前mysql版本是否支持:show variables like 'profiling'

  2. 开启功能,默认是关闭,使用前需开启:set profiling=on

  3. 运行sql。会自动记录该sql。

  4. 查看结果:show profiles;(返回Query_ID=这条sql的id、Duration=执行时间、Query=具体sql语句)

  5. 诊断sql:show profile [type] for query 问题SQL的Query_ID(可以查看到阶段及开销信息)
    type可选值如下:

    • all:显示所有开销信息
    • block io:显示块IO相关开销
    • context switches:上下文切换相关开销
    • cpu:显示cpu相关开销信息
    • ipc:显示发送和接收相关开销信息
    • memory:显示内存相关开销信息
    • page faults:显示页面错误相关开销信息
    • source:显示和soure_function、source_file、source_line相关的开销信息
    • swaps:显示交换次数相关的开销信息

    一般查询cpu和io,即show profile cpu,block io for query 问题SQL的Query_ID

危险阶段

  • converting HEAP to MyISAM:查询结果太大,内存不够用,往磁盘上搬。
  • Creating tmp table:创建临时表。需要先拷贝数据到临时表,用完后才删除。非常耗时!
  • Copying to tmp table on disk:把内存中的临时表复制到磁盘,非常危险!
  • locked

全局查询日志

  • 永远不要在生产环境启用
  • 可以在配置文件my.cnf中配置实用。
  • 开启:set global general_log=1+以表形式输出set global log_output='TABLE'
  • 查询日志:select * from mysql.general_log

优化sql步骤

  1. 开启慢查询日志捕获慢SQL
  2. 使用EXPLAIN分析慢SQL
  3. 使用show profile查询SQL在Mysql服务器里面的执行细节和生命周期情况
  4. SQL数据库服务器的参数调优

Mysql锁机制

  • 锁是计算机协调多个进程或线程并发访问某一资源的机制。

锁的分类

  • 从数据操作类型分:读锁(共享锁)、写锁(排它锁)。

    1. 读锁,也称共享锁。是针对同一份数据,多个读操作可以同时进行而不会互相影响。
      所有人都可读,占有读锁的人不可以读其他表(即使该表没上锁),自己不可写当前表(error),其他人写了加读锁的表会阻塞。
    2. 写锁,也称排它锁。当前写操作没有完成前,它会阻塞其他写锁与读锁。拥有写锁的人可以修改当前表,可以查询当前表,不能查询其他表(error),其他人查询、写操作被写锁锁住的表会阻塞(等释放锁的时候返回结果)。
    • 读锁会阻塞写,但不会堵塞读。写锁会把读和写都阻塞。
锁类型可否兼容读锁写锁
读锁
写锁
  • 从对数据操作的粒度分:表锁(偏读)、行锁(偏写)。(页锁位于表锁和行锁之间,并发度一般)

    1. 表锁:偏向MyISAM存储引擎,开销小,加锁快;无死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
      注:MyISAM 存储引擎的读写锁调度是写优先,因此MyISAM不适合做写为主表的存储引擎。因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永远阻塞。
    2. 行锁:偏向InnoDB存储引擎,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
      注:InnoDB与MyISAM最大的不同是:InnoDB支持事务,且采用了行级锁。
    • 索引失效,会导致行锁变成表锁!
  • 操作SQL语句

    1. 查看锁:show open tables查询的是所有表(0表示没有锁,1表示被加锁了)
    2. 添加表锁:lock table table1_name read | write [, table2_name read | write ... ]
    3. 释放表锁:unlock tables;
    4. 查看表锁定状态:show status like 'table%';,返回table_locks_waited(产生表级锁定次数)和table_locks_immediate(出现表级锁定争用而发生等待的次数)状态变量。
    5. 查看InnoDB行锁争夺情况:show status like 'innodb_row_lock%';,会返回几个参数,其中Innodb_row_lock_waits表示系统启动后到现在总共等待的次数;Innodb_row_lock_time表示等待总时长;Innodb_row_lock_time_avg表示等待平均时长。
  • 间隙锁:当我们用范围条件而不是相等条件检索数据,并请求共享或排它锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”。InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-key锁)。即宁可错杀,不可放过。因此也会对系统性能造成危害。
    应避免间隙锁。

  • 如何锁定一行?
    在sql语句后面添加select ... for update,保证该sql语句执行commit后其他sql语句才能执行。

主从复制

MySQL复制过程:

  1. master将改变 记录到二进制日志(binary log)。这些记录过程叫做二进制日志事件,binary log events。
  2. slave将master的binary log events拷贝到它的中继日志(relay log)。
  3. slave重做中继日志中的事件,将改变应用到自己的数据库中。MySQL复制是异步的且串行化的。

复制的基本原则:

  • 每个slave只有一个master
  • 每个slave只能有一个唯一的服务器ID
  • 每个master可以有多个slave

复制的最大问题:

  • 延迟

主从配置视频链接

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值