Mysql问题收集

主从同步流程

异步模式

主节点

1、当主节点上进行 insert、update、delete 操作时,会按照时间先后顺序写入到 binlog 中;
2、当从节点连接到主节点时,主节点会创建一个叫做 binlog dump 的线程;

3、一个主节点有多少个从节点,就会创建多少个 binlog dump 线程;

4、当主节点的 binlog 发生变化的时候,也就是进行了更改操作,binlog dump 线程就会通知从节点 (Push模式),并将相应的 binlog 内容发送给从节点;

从节点

当开启主从同步的时候,从节点会创建两个线程用来完成数据同步的工作。

I/O线程: 此线程连接到主节点,主节点上的 binlog dump 线程会将 binlog 的内容发送给此线程。此线程接收到 binlog 内容后,再将内容写入到本地的 relay log,并将读取到的主库bin log文件名和位置position记录到master-info文件中,以便在下一次读取用;

SQL线程: 该线程读取 I/O 线程写入的 relay log,并且根据 relay log 的内容对从数据库做对应的操作。

主从配置一般都是和读写分离相结合,主服务器负责写数据,从服务器负责读数据,并保证主服务器的数据及时同步到从服务器。

全同步模式

指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。

半同步模式

介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用

binlog记录格式

MySQL 主从复制有三种方式:基于SQL语句的复制(statement-based replication,SBR),基于行的复制(row-based replication,RBR),混合模式复制(mixed-based replication,MBR)。对应的binlog文件的格式也有三种:STATEMENT,ROW,MIXED。

  • Statement-base Replication (SBR)就是记录sql语句在bin log中,Mysql 5.1.4 及之前的版本都是使用的这种复制格式。优点是只需要记录会修改数据的sql语句到binlog中,减少了binlog日质量,节约I/O,提高性能。缺点是在某些情况下,会导致主从节点中数据不一致(比如sleep(),now()等)。
  • Row-based Relication(RBR)是mysql master将SQL语句分解为基于Row更改的语句并记录在bin log中,也就是只记录哪条数据被修改了,修改成什么样。优点是不会出现某些特定情况下的存储过程、或者函数、或者trigger的调用或者触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是修改table的时候会让日志暴增,同时增加bin log同步时间。也不能通过bin log解析获取执行过的sql语句,只能看到发生的data变更。
  • Mixed-format Replication(MBR),MySQL NDB cluster 7.3 和7.4 使用的MBR。是以上两种模式的混合,对于一般的复制使用STATEMENT模式保存到binlog,对于STATEMENT模式无法复制的操作则使用ROW模式来保存,MySQL会根据执行的SQL语句选择日志保存方式。

选型与配置

mysql主从模式默认是异步复制的,而MySQL Cluster是同步复制的,只要设置为相应的模式即是在使用相应的同步策略。

从MySQL5.5开始,MySQL以插件的形式支持半同步复制。其实说明半同步复制是更好的方式,兼顾了同步和性能的问题。

集群方案

  1. 首先反对大家做读写分离,关于这方面的原因解释太多次数(增加技术复杂度、可能导致读到落后的数据等),只说一点:99.8%的业务场景没有必要做读写分离,只要做好数据库设计优化 和配置合适正确的主机即可。

2.Keepalived+MySQL --确实有脑裂的问题,还无法做到准确判断mysqld是否HANG的情况;

3.DRBD+Heartbeat+MySQL --同样有脑裂的问题,还无法做到准确判断mysqld是否HANG的情况,且DRDB是不需要的,增加反而会出问题;

3.MySQL Proxy -- 不错的项目,可惜官方半途夭折了,不建议用,无法高可用,是一个写分离;

4.MySQL Cluster -- 社区版本不支持NDB是错误的言论,商用案例确实不多,主要是跟其业务场景要求有关系、这几年发展有点乱不过现在已经上正规了、对网络要求高;

5.MySQL + MHA -- 可以解决脑裂的问题,需要的IP多,小集群是可以的,但是管理大的就麻烦,其次MySQL + MMM 的话且坑很多,有MHA就没必要采用MMM

事务

redo

它记录的是数据库中每个页的修改,而不是某一行或某几行修改成怎样,可以用来恢复提交后的物理数据页,且只能恢复到最后一次提交的位置。

有了redo以后,innodb引擎会把更新记录先写入redo log中,再修改Buffer Bool中的数据,这个时候状态为prepare状态,还未真正提交成功,要等bin log写入磁盘以后,才会变成为commit状态,事务才算是提交完成。

至于缓存中更新的数据文件何时刷入磁盘,则由后台线程异步处理,这样即使缓存刷入磁盘发生宕机,也可以在重启时解析redo log重新刷盘。

redo log用到了WAL(Write-Ahead Logging)技术,这个技术的核心就在于修改记录前,一定要先写日志,并保证日志先落盘,才能算事务提交完成。

redo log日志满了,在擦除之前,需要确保这些要被擦除记录对应在内存中的数据页都已经刷到磁盘中了。擦除旧记录腾出新空间这段期间,是不能再接收新的更新请求的,此刻MySQL的性能会下降。所以在并发量大的情况下,合理调整redo log的文件大小非常重要。

undo

如其名主要起到回滚的作用,它是保证事务原子性的关键。记录的是数据修改前的状态,在数据修改的流程中,同时会记录一条与当前操作相反的逻辑日志到undo log中。

我们举个栗子:假如更新ID=1记录的name字段,name原始数据为小富,现改name为程序员内点事

事务执行update X set name = 程序员内点事 where id =1语句时,先会在undo log中记录一条相反逻辑的update X set name = 小富 where id =1记录,这样当某些原因导致服务异常事务失败,就可以借助undo log将数据回滚到事务执行前的状态,保证事务的完整性。

bin log与redo log区别

  • 层次不同:redo log 是InnoDB存储引擎实现的,bin log 是MySQL的服务器层实现的,但MySQL数据库中的任何存储引擎对于数据库的更改都会产生bin log。
  • 作用不同:redo log 用于碰撞恢复(crash recovery),保证MySQL宕机也不会影响持久性;bin log 用于时间点恢复(point-in-time recovery),保证服务器可以基于时间点恢复数据和主从复制。
  • 内容不同:redo log 是物理日志,内容基于磁盘的页Page;bin log的内容是二进制,可以根据binlog_format参数自行设置。
  • 写入方式不同:redo log 采用循环写的方式记录;binlog 通过追加的方式记录,当文件大小大于给定值后,后续的日志会记录到新的文件上。
  • 刷盘时机不同:bin log在事务提交时写入;redo log 在事务开始时即开始写入。

bin log 与 redo log 功能并不冲突而是起到相辅相成的作用,需要二者同时记录,才能保证当数据库发生宕机重启时,数据不会丢失。

MySql更新流程

MySQL更新数据的基础流程,其中包括redo logbin logundo log三种日志间的大致关系

三种日志总结

undo log让mysql有回滚事物的能力,redo log让mysql有崩溃恢复的能力,以及我们现在说的bin log让MySQL有搭建集群、数据备份、恢复数据的能力

问题

手动用begin开启事务,然后执行update语句,再然后执行commit语句,那上面的update更新流程哪些是update语句执行之后做的,哪些是commit语句执行之后做的?

实际上,redo log在内存中有一个redo log buffer,binlog 也有一个binlog cache.所以在手动开启的事务中,你执行sql语句,其实是写到redo log buffer和binlog cache中去的(肯定不可能是直接写磁盘日志,一个是性能差一个是回滚的时候不可能去回滚磁盘日志吧),然后当你执行commit的时候,首先要将redo log的提交状态游prepare改为commit状态,然后就要把binlog cache刷新到binlog日志(可能也只是flush到操作系统的page cache,这个就看你的mysql配置),redo log buffer刷新到redo log 日志(刷新时机也是可以配置的)。 如果你回滚的话,就只用把binlog cache和redo log buffer中的数据清除就行了。

在update过程中,mysql突然宕机,会发生什么情况?

1.如果redolog写入了,处于prepare状态,binlog还没写入,那么宕机重启后,redolog中的这个事务就直接回滚了。

2.如果redolog写入了,binlog也写入了,但redolog还没有更新为commit状态,那么宕机重启以后,mysql会去检查对应事务在binlog中是否完整。如果是,就提交事务;如果不是,就回滚事务。 (redolog处于prepare状态,binlog完整启动时就提交事务,为啥要这么设计? 主要是因为binlog写入了,那么就会被从库或者用这个binlog恢复出来的库使用,为了数据一致性就采用了这个策略) redo log和binlog是通过xid这个字段关联起来的。

MVCC 多版本并发控制

通过多版本并发控制MVCC解决不可重复读问题,加上间隙锁(也就是并发控制)解决幻读问题。因此InnodbRR隔离级别其实实现了串行化级别的效果,而且保留了比较好的并发性能。

MVCC解决读写互不阻塞和不重复读的问题

MVCC只在READ COMMITTEDREPEATABLE READ 两个隔离级别下工作。其他两个隔离级别够和MVCC不兼容。

因为 READ UNCOMMITTED 总是读取最新的数据行, 而不是符合当前事务版本的数据行。而 SERIALIZABLE 则会对所有读取的行都加锁。

Undo日志版本链

undolog隐藏两个字段trx_id(事务id)roll_pointer(指向上一次修改记录指针)

ReadView一致性视图

RR和RC生成一致性视图的时机不一样 (这也是两种隔离级别实现的主要区别)

  • 读提交(read committed RC) 是在每一次select的时候生成ReadView的

  • 可重复读(repeatable read RR)是在第一次select的时候生成ReadView的

区别:RC在事务过程中,如果有其他事务提交了,可以读取到,但是RR不可以

比如:事务A60,事务B61,61修改并提交,RC是可以读取到新的提交的,RR不可以。

查询生成的ReadView中包含trx_ids数组,就是当前未提交事务id的集合

版本链比对规则:

min_id,max_id分别表示trx_ids中最小的事务id,最大的事务id

  1. 如果 row 的 trx_id 落在绿色部分( trx_id<min_id ),表示这个版本是已提交的事务生成的,这个数据是可见的;
  2. 如果 row 的 trx_id 落在红色部分( trx_id>max_id ),表示这个版本是由将来启动的事务生成的,是不可见的(若 row 的 trx_id 就是当前自己的事务是可见的);
  3. 如果 row 的 trx_id 落在黄色部分(min_id <=trx_id<= max_id),那就包括两种情况
    1. 若 row 的 trx_id 在视图数组中,表示这个版本是由还没提交的事务生成的,不可见(若 row 的 trx_id 就是当前自己的事务是可见的);
    2. 若 row 的 trx_id 不在视图数组中,表示这个版本是已经提交了的事务生成的,可见。

我劝!这位年轻人不讲MVCC,耗子尾汁!

京东面试官问我:“聊聊MySql事务,MVCC?”

Mysql事务隔离与锁

  • 未提交读:事务A中修改完数据M后,立刻对这个数据M加上共享锁(S锁)[当事务A继续修改数据M的时候,先释放掉S锁,再修改数据,再加上S锁],根据S锁的特性,事务B可以读到事务A修改后的数据(无论事务A是否提交,因为是共享锁,随时随地都能查到数据A修改后的结果),事务B不能去修改数据M,直到事务A提交,释放掉S锁。
  • 已提交读:事务A在修改数据M后立刻加X锁,事务B不能修改数据M,同时不能查询到最新的数据M(避免脏读),查询到的数据M是上一个版本(Innodb MVCC快照)的
  • 可重复读:是在已提交读的基础上,对读到的数据M瞬间加上共享锁,直到事务结束才释放(保证了其他事务没办法修改该数据)
  • 串行化:是从MVCC并发控制退化到基于锁的并发控制,对事务中所有读取操作加S锁,写操作加X锁,这样可以避免脏读,不可重复读,幻读,更新丢失,开销也最大,会造成读写冲突,并发程度也最低。

Mysql 当前读 快照读

MySQL-当前读、快照读、MVCC

当前读

  • select...lock in share mode (共享读锁)
  • select...for update
  • update , delete , insert

当前读的实现方式:next-key锁(行记录锁+Gap间隙锁)
间隙锁:只有在Read RepeatableSerializable隔离级别才有,就是锁定那些范围空间内的数据,假设锁定id>3的数据,id有3,4,5,那么4,5和后面的数字都会被锁定,像6,7...,为什么要这样?因为如果我们不锁定没有的数据,当加入了新的数据id=6,就会出现幻读,间隙锁避免了幻读。

快照读

单纯的select操作,不包括上述 select ... lock in share mode, select ... for update。    
Read Committed隔离级别:每次select都生成一个快照读
Read Repeatable隔离级别:开启事务后第一个select语句才是快照读的地方,而不是一开启事务就快照读

快照读的实现方式:undolog和多版本并发控制MVCC

Mysql explain 优化

  • system: 表中只有一条数据. 这个类型是特殊的 const 类型.

  • const: 针对主键或唯一索引的等值查询扫描, 最多只返回一行数据. const 查询速度非常快, 因为它仅仅读取一次即可.
    例如下面的这个查询, 它使用了主键索引, 因此 type 就是 const 类型的.

    explain select * from user_info where id = 2
    
  • eq_ref: 此类型通常出现在多表的 join 查询, 表示对于前表的每一个结果, 都只能匹配到后表的一行结果. 并且查询的比较操作通常是 =, 查询效率较高.

    EXPLAIN SELECT * FROM user_info, order_info WHERE user_info.id = order_info.user_id
    
  • ref: 此类型通常出现在多表的 join 查询, 针对于非唯一或非主键索引, 或者是使用了 最左前缀 规则索引的查询.

    EXPLAIN SELECT * FROM user_info, order_info WHERE user_info.id = order_info.user_id AND order_info.user_id = 5
    
  • range: 表示使用索引范围查询, 通过索引字段范围获取表中部分数据记录. 这个类型通常出现在 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN() 操作中.
    typerange 时, 那么 EXPLAIN 输出的 ref 字段为 NULL, 并且 key_len 字段是此次查询中使用到的索引的最长的那个.
  • index: 表示全索引扫描(full index scan), 和 ALL 类型类似, 只不过 ALL 类型是全表扫描, 而 index 类型则仅仅扫描所有的索引, 而不扫描数据.
    index 类型通常出现在: 所要查询的数据直接在索引树中就可以获取到, 而不需要扫描数据. 当是这种情况时, Extra 字段 会显示 Using index.
  • ALL: 表示全表扫描, 这个类型的查询是性能最差的查询之一. 通常来说, 我们的查询不应该出现 ALL 类型的查询, 因为这样的查询在数据量大的情况下, 对数据库的性能是巨大的灾难. 如一个查询是 ALL 类型查询, 那么一般来说可以对相应的字段添加索引来避免.
    下面是一个全表扫描的例子, 可以看到, 在全表扫描时, possible_keys 和 key 字段都是 NULL, 表示没有使用到索引, 并且 rows 十分巨大, 因此整个查询效率是十分低下的.

type 类型的性能比较

通常来说, 不同的 type 类型的性能关系如下:
ALL < index < range ~ index_merge < ref < eq_ref < const < system
ALL 类型因为是全表扫描, 因此在相同的查询条件下, 它是速度最慢的.
index 类型的查询虽然不是全表扫描, 但是它扫描了所有的索引, 因此比 ALL 类型的稍快.
后面的几种类型都是利用了索引来查询数据, 因此可以过滤部分或大部分数据, 因此查询效率就比较高了.

MySQL 性能优化神器 Explain 使用分析

联合索引在B+树上的结构

首先,表T1有字段a,b,c,d,e,其中a是主键,除e为varchar其余为int类型,并创建了一个联合索引idx_t1_bcd(b,c,d),然后b、c、d三列作为联合索引,在B+树上的结构正如上图所示。联合索引的所有索引列都出现在索引数上,并依次比较三列的大小。

联合索引在B+树上的存储结构及数据查找方式

Mysql中的innodb与myisam区别?

  1. InnoDB 支持事务,MyISAM 不支持事务。这是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;

  2. InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败;

  3. InnoDB 是聚集索引,MyISAM 是非聚集索引。聚簇索引的文件存放在主键索引的叶子节点上,因此 InnoDB 必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而 MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。

  4. InnoDB 不保存表的具体行数,执行 select count(*) from table 时需要全表扫描。而MyISAM 用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;

  5. InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁。一个更新语句会锁住整张表,导致其他查询和更新都会被阻塞,因此并发访问受限。这也是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;

索引的几大原则

1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

2.=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式。

3.尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录。

4.索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’)。

5.尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。

慢查询优化基本步骤

  1. 先运行看看是否真的很慢,注意设置SQL_NO_CACHE

  2. where条件单表查,锁定最小返回记录表。这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始查起,单表每个字段分别查询,看哪个字段的区分度最高

  3. explain查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询)

  4. order by limit 形式的sql语句让排序的表优先查

  5. 了解业务方使用场景

  6. 加索引时参照建索引的几大原则

  7. 观察结果,不符合预期继续从0分析

mysql索引失效的场景

  • 使用!= 或者 <> 导致索引失效
  • 字类型不一致导致的索引失效(字段类型与查询条件类型不一致)
  • 函数导致的索引失效
  • 运算符导致的索引失效
    SELECT * FROM user WHERE age - 1 = 20;
    
  • OR引起的索引失效

    OR导致索引是在特定情况下的,并不是所有的OR都是使索引失效,如果OR连接的是同一个字段,那么索引不会失效,反之索引失效。

  • 模糊搜索导致的索引失效

MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!

导致MySQL索引失效的几种常见写法

MySQL - 负向查询完全不能走索引么?

「MySQL系列」索引设计原则、索引失效场景、limit 、order by、group by 等常见场景优化

mysql对千万级数据的优化

mysql数据表规模90000000(九千万)左右,怎么优化查询?

MySQL 对于千万级的大表要怎么优化?

mysql对执行语句分析

mysql索引命中分析

MySQL索引原理及慢查询优化

为什么不建议将字段设置为可以为null

  • Null 列需要更多的存储空间:需要一个额外字节作为判断是否为 NULL 的标志位
  • NOT IN、!= 等负向条件查询在有 NULL 值的情况下返回永远为空结果,查询容易出错

MySQL 一千个不用 Null 的理由

or 、in | not in 、is null | is not null、!=、<>,使用,是否走索引

  1. 全表扫描是否比索引更快,以至于优化器选择全表扫描
  2. mysql-server 的版本。。。
  3. 可以通过优化语法或者配置优化器,走索引

not in或者!=会导致索引失效并不是绝对的 对于数据较为均匀的场景是会失效的 但是如果业务数据严重不均的字段加了索引的话是不一定失效的 mysql自己会做判断 并不是绝对判定不使用索引 比如表A性别列有男10000条女20条,当sex!=’男‘是可以使用索引的 同样的如果你sex='男'反而不会使用索引 mysql自己会选择最优的检索方式

那既然IS NULLIS NOT NULL!=这些条件都可能使用到索引,那到底什么时候索引,什么时候采用全表扫描呢?

答案很简单:成本。当然,关于如何定量的计算使用某个索引执行查询的成本比较复杂,我们在小册中花了很大的篇幅来唠叨了。不过因为篇幅有限,我们在这里只准备定性的分析一下。对于使用二级索引进行查询来说,成本组成主要有两个方面:

  • 读取二级索引记录的成本
  • 将二级索引记录执行回表操作,也就是到聚簇索引中找到完整的用户记录的操作所付出的成本。

很显然,要扫描的二级索引记录条数越多,那么需要执行的回表操作的次数也就越多,达到了某个比例时,使用二级索引执行查询的成本也就超过了全表扫描的成本(举一个极端的例子,比方说要扫描的全部的二级索引记录,那就要对每条记录执行一遍回表操作,自然不如直接扫描聚簇索引来的快)。

所以MySQL优化器在真正执行查询之前,对于每个可能使用到的索引来说,都会预先计算一下需要扫描的二级索引记录的数量,比方说对于下边这个查询:

SELECT * FROM s1 WHERE key1 IS NULL;

优化器会分析出此查询只需要查找key1值为NULL的记录,然后访问一下二级索引idx_key1,看一下值为NULL的记录有多少(如果符合条件的二级索引记录数量较少,那么统计结果是精确的,如果太多的话,会采用一定的手段计算一个模糊的值,当然算法也比较麻烦,我们就不展开说了,小册里有说),这种在查询真正执行前优化器就率先访问索引来计算需要扫描的索引记录数量的方式称之为index dive。当然,对于某些查询,比方说WHERE子句中有IN条件,并且IN条件中包含许多参数的话,比方说这样:

SELECT * FROM s1 WHERE key1 IN ('a', 'b', 'c', ... , 'zzzzzzz');

这样的话需要统计的key1值所在的区间就太多了,这样就不能采用index dive的方式去真正的访问二级索引idx_key1,而是需要采用之前在背地里产生的一些统计数据去估算匹配的二级索引记录有多少条(很显然根据统计数据去估算记录条数比index dive的方式精确性差了很多)。

反正不论采用index dive还是依据统计数据估算,最终要得到一个需要扫描的二级索引记录条数,如果这个条数占整个记录条数的比例特别大,那么就趋向于使用全表扫描执行查询,否则趋向于使用这个索引执行查询。

理解了这个也就好理解为什么在WHERE子句中出现IS NULLIS NOT NULL!=这些条件仍然可以使用索引,本质上都是优化器去计算一下对应的二级索引数量占所有记录数量的比值而已。

MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!

MySQL索引原理及慢查询优化

无效索引

  • 如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引
  • 对于多列索引,不是使用的第一部分(第一个),则不会使用索引,就是未匹配到最左匹配原则
  • like查询是以%开头
  • 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
  • where查询条件中,对列使用了函数的(day(column)=....
  • 如果mysql估计使用全表扫描要比使用索引快,则不使用索引

Mysql索引失效的几种情况

Mysql有效索引和无效索引的介绍

MySQL高级 之 索引失效与优化详解

索引性能优化

  • 最左匹配原则
  • 覆盖索引
  • 索引下推

MySQL 5.6中 引入的索引下推优化(index condition push down), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数,比如 like '张%'

参考:

面试官你好,我已经掌握了MySQL主从配置和读写分离,你看我还有机会吗?

MySQL 半同步复制模式说明及配置示例 - 运维小结

MySQL主从同步详解与配置

MySQL集群之五大常见的MySQL高可用方案(转)

高性能、高可用、可扩展的MySQL集群如何组建?

MySQL不会丢失数据的秘密,就藏在它的 7种日志里

MySQL必知必会:简介undo log、truncate、以及undo log如何帮你回滚事务

理解 MySQL 一致性非锁定读原理

MySQL · 引擎特性 · 庖丁解InnoDB之REDO LOG

mysql_一条更新语句的执行流程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章