开发人员必备的9大MySQL索引和查询优化一般来说,程序员的面试内容分为两部分,一部分与编程相关,另一部分则与数据库相关。而作为数据库中的主流,MySQL更是涉及面试中的诸多高频考点。对于后端人员来说,不需要像专业的DBA那样精通MySQL,但也需要掌握相关的基本内容。小编在此总结了MySQL面试中常见7大领域的50道经典面试题,以期帮助大家顺利通过面试。
首先,看看下面的MySQL知识树。从图中可以看出,MySQL可以从开发、优化、维护3方面来展开学习。其中,索引、锁、事务、优化等问题更是反复出现,是面试的重中之重。本篇文章就将聚焦于存储引擎、数据类型、索引、锁、事务、表结构、优化等常见的7大领域。
一、存储引擎相关
1.你知道哪些MySQL存储引擎?
- InnoDB。这是最常用的事务型存储引擎;
- MyISAM。这是最常用的非事务型存储引擎,也是MySQL5.6之前的默认引擎;
- MEMORY。这是一种易失性非事务型存储引擎;
- ARCHIVE。这是一种只允许查询和新增数据而不允许修改的非事务型存储引擎;
- CSV。这是以CSV格式存储的非事务型存储引擎;
- MERGE。将多个类似的MyISAM表分组为一个表,可以处理非事务性表,默认情况下包括这些表。
- EXAMPLE。可以使用此引擎创建表,但不能存储或获取数据。
- BLACKHOLE。接受要存储的数据,但始终返回空。
- FEDERATED。将数据存储在远程数据库中。
2.常见的存储引擎都适用于哪些场景?
使用哪一种引擎需要灵活选择,合适的存储引擎,能够提高整个数据库的性能。不同的存储引擎都有各自的特点,以适应不同的需求,如下表所示:
3.InnoDB和MyISAM的区别有哪些?
- InnoDB支持事物,而MyISAM不支持事物;
- InnoDB支持行级锁,而MyISAM支持表级锁;
- InnoDB支持MVCC, 而MyISAM不支持;
- InnoDB支持外键,而MyISAM不支持;
- InnoDB不支持全文索引,而MyISAM支持。
4、InnoDB和MyISAM,select count(*)哪个更快,为什么?
MyISAM更快。因为MyISAM内部维护了一个计数器,可以直接调取。
5、MyISAM Static和MyISAM Dynamic有什么区别?
- 在MyISAM Static上的所有字段有固定宽度;
- 动态MyISAM表将具有像TEXT,BLOB等字段,以适应不同长度的数据类型;
- MyISAM Static在受损情况下更容易恢复。
二、数据类型相关
6. char和varchar的区别是什么?
- char是一个定长字段,如果申请了
char(10)
的空间,那么无论实际存储多少内容,该字段都占用10个字符; - varchar是变长的,也就是说申请的只是最大长度,占用的空间为实际字符长度 1;
- 在检索效率上来讲,char > varchar。因此在使用中,如果确定某个字段的值的长度,可以使用char,否则应该尽量使用varchar。例如存储用户MD5加密后的密码,则应该使用char。
7.varchar(10)和int(10)分别有什么含义?
- varchar的10代表了申请的空间长度,也是可以存储的数据的最大长度;
- int的10只是代表了展示的长度,不足10位以0填充。也就是说,int(1)和int(10)所能存储的数字大小以及占用的空间都是相同的,只是在展示时按照长度展示而已。
8.MySQL的binlog有几种录入格式,它们之间有什么区别?
有三种格式:statement、row和mixed。
- statement模式下,记录单元为语句。即每一个sql造成的影响会记录。由于sql的执行是有上下文的,因此在保存的时候需要保存相关的信息,同时还有一些使用了函数之类的语句无法被记录复制。
- row级别下,记录单元为每一行的改动,基本是可以全部记下来但是由于很多操作,会导致大量行的改动(比如alter table),因此这种模式的文件保存的信息太多,日志量太大。
- mixed, 一种折中的方案,普通操作使用statement记录,当无法使用statement的时候使用row。
9.如何在Unix和MySQL时间戳之间进行转换?
- 从Unix时间戳转换为MySQL时间戳可以使用FROM_UNIXTIME命令
- 从MySQL时间戳转换为Unix时间戳可以使用UNIX_TIMESTAMP命令
10.怎样才能找出最后一次插入时分配了哪个自动增量?
LAST_INSERT_ID将返回由Auto_increment分配的最后一个值,并且不需要指定表名称。
11.列设置为AUTO INCREMENT时,如果在表中达到最大值,会发生什么情况?
它会停止递增,任何进一步的插入都将产生错误,因为密钥已被使用。
12.MySQL中,如果一个表有一列定义为TIMESTAMP,则会发生什么?
每当行被更改时,时间戳字段将获取当前时间戳。
13. 如果要存储用户的密码散列,应该使用什么字段进行存储?
密码散列、用户身份证号等固定长度的字符串,应该使用char而不是varchar来存储,这样可以节省空间且提高检索效率。
三、索引相关
14. 什么是索引?
索引是一种数据结构,可以帮助我们快速地进行数据的查找。
15.索引有什么优缺点?
索引的优点有:
- 可以保证数据库表中每一行的数据的唯一性
- 可以大大加快数据的索引速度
- 加速表与表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
- 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间
- 通过使用索引,可以在时间查询的过程中,使用优化隐藏器,提高系统的性能
索引的缺点有:
- 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加
- 索引需要占物理空间,除了数据表占用数据空间之外,每一个索引还要占用一定的物理空间,如果需要建立聚簇索引,那么需要占用的空间会更大
- 以表中的数据进行增、删、改的时候,索引也要动态的维护,这就降低了整数的维护速度
16.索引的数据结构和什么有关?
- 索引的数据结构和具体存储引擎的实现有关;在MySQL中使用较多的索引有Hash索引,B 树索引等。
- 我们经常使用的InnoDB存储引擎的默认索引实现为:B 树索引。
17.MySQL主要的索引类型有哪些?
- 普通索引。是最基本的索引,它没有任何限制;
- 唯一索引。索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一;
- 主键索引。是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值;
- 组合索引。指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用,使用组合索引时遵循最左前缀集合;
- 全文索引:主要用来查找文本中的关键字,而不是直接与索引中的值相比较,mysql中MyISAM支持全文索引而InnoDB不支持。
18. 在建立索引的时候,需要考虑哪些因素?
- 建立索引的时候一般要考虑到字段的使用频率,经常作为条件进行查询的字段比较适合;
- 如果需要建立联合索引的话,还需要考虑联合索引中的顺序;
- 此外也要考虑其他方面,比如防止过多的所有对表造成太大的压力,这些都和实际的表结构以及查询方式有关。
19. Hash索引和B 树索引有什么区别?
首先要知道Hash索引和B 树索引的底层实现原理:
- hash索引底层就是hash表,进行查找时,调用一次hash函数就可以获取到相应的键值,之后进行回表查询获得实际数据。
- B 树底层实现是多路平衡查找树。对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据。
可以看出他们有以下的不同:
- 一般情况下,hash索引进行等值查询更快,但是却无法进行范围查询。因为在hash索引中经过hash函数建立索引之后,索引的顺序与原顺序无法保持一致,不能支持范围查询。而B 树的的所有节点皆遵循(左节点小于父节点,右节点大于父节点,多叉树也类似),天然支持范围。
- hash索引不支持使用索引进行排序,原因同上;
- hash索引不支持模糊查询以及多列索引的最左前缀匹配。原因也是因为hash函数的不可预测。AAAA和AAAAB的索引没有相关性。
- hash索引任何时候都避免不了回表查询数据,而B 树在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询。
- hash索引虽然在等值查询上较快,但是不稳定,性能不可预测。当某个键值存在大量重复的时候,发生hash碰撞,此时效率可能极差。而B 树的查询效率比较稳定,对于所有的查询都是从根节点到叶子节点,且树的高度较低。
因此,在大多数情况下,直接选择B 树索引可以获得稳定且较好的查询速度,而不需要使用hash索引。
20. 非聚簇索引一定会回表查询吗?
不一定。这涉及到查询语句所要求的字段是否全部命中了索引,如果全部命中了索引,那么就不必再进行回表查询。
举个简单的例子,假设我们在员工表的年龄上建立了索引,那么当进行select age from employee where age < 20
的查询时,在索引的叶子节点上,已经包含了age信息,不会再次进行回表查询。
21. 什么是联合索引?为什么需要注意联合索引中的顺序?
MySQL可以使用多个字段同时建立一个索引,叫做联合索引。在联合索引中,如果想要命中索引,需要按照建立索引时的字段顺序挨个使用,否则无法命中索引。
具体原因为:
MySQL使用索引时需要索引有序,假设现在建立了"name,age,school"的联合索引,那么索引的排序为:先按照name排序,如果name相同,则按照age排序,如果age的值也相等,则按照school进行排序。
当进行查询时,此时索引仅仅按照name严格有序,因此必须首先使用name字段进行等值查询,之后对于匹配到的列而言,其按照age字段严格有序,此时可以使用age字段用做索引查找……因此在建立联合索引的时候应该注意索引列的顺序,一般情况下,将查询需求频繁或者字段选择性高的列放在前面。此外可以根据特例的查询或者表结构进行单独的调整。
22. 怎样知道语句运行很慢的原因?
MySQL提供了explain命令来查看语句的执行计划。
MySQL在执行某个语句之前,会将该语句过一遍查询优化器,之后会拿到对语句的分析,也就是执行计划,其中包含了许多信息。可以通过其中和索引有关的信息来分析是否命中了索引,例如possilbe_key、key、key_len等字段,分别说明了此语句可能会使用的索引,实际使用的索引以及使用的索引长度。
23. 为何会发生针对该列创建了索引但是在查询的时候并没有使用的问题?
在下面情况下,MySQL无法使用索引:
- 使用不等于查询;
- 列参与了数学运算或者函数;
- 在字符串like时左边是通配符,类似于'�a';
- 当mysql分析全表扫描比使用索引快的时候不使用索引;
- 当使用联合索引,前面一个条件为范围查询,后面的即使符合最左前缀原则,也无法使用索引。
更多 索引 相关精彩内容
开发人员必备的9大MySQL索引和查询优化
彻底搞懂MySQL的索引
mysql性能优化之一【索引--基础】
四、锁相关
24. 你对MySQL锁是怎么理解的?
当数据库有并发事务的时候,可能会产生数据的不一致,这时候需要一些机制来保证访问的次序,锁机制就是这样的一个机制。
就像酒店的房间,如果大家随意进出,就会出现多人抢夺同一个房间的情况,而在房间上装上锁,申请到钥匙的人才可以入住并且将房间锁起来,其他人只有等他使用完毕才可以再次使用。
25.加锁有什么好处?
数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。
加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。
26.Mysql中有哪几种锁?
- 表级锁。开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低;
- 行级锁。开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高;
- 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
27.什么是死锁?锁等待?通过数据库哪些表可以监控?
- 死锁是指两个或多个事务在同一资源上互相占用,并请求加锁时,而导致的恶性循环现象。当多个事务以不同顺序试图加锁同一资源时,就会产生死锁。
- 锁等待:mysql数据库中,不同session在更新同行数据中,会出现锁等待;
- 重要的三张锁的监控表innodb_trx,innodb_locks,innodb_lock_waits
28.MySQL中InnoDB引擎的行锁是如何实现的?
- InnoDB是基于索引来完成行锁
- 例如,select * from tab_with_index where id = 1 for update;for update 可以根据条件来完成行锁锁定,并且 id 是有索引键的列,如果 id 不是索引键那么InnoDB将完成表锁。
29.你知道哪些优化锁的方法?
- 读写分离;
- 分段加锁;
- 减少锁持有的时间;
- 多个线程尽量以相同的顺序去获取资源;
- 尽可能让所有的数据检索都通过索引来完成;
- 合理设计索引;
- 尽可能减少基于范围的数据检索过滤条件;
- 不要将锁的粒度过于细化,不然可能会出现线程的加锁和释放次数过多,反而效率不如一次加一把大锁。
更多 锁 相关精彩内容
Java中的锁原理、锁优化、CAS、AQS,看这篇就对了!
redis实现分布式锁
面试题【synchronized 的实现原理以及锁优化】
初识同步锁
Mysql排它锁演示
五、事务相关
30. 什么是事务?
事务是一系列的操作,他们要符合ACID特性。
最常见的理解就是:事务中的操作要么全部成功,要么全部失败。
31. ACID是什么?
ACID,是数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
- A=Atomicity,指的是原子。即要么全部成功,要么全部失败,不可能只执行一部分操作。
- C=Consistency,指的是一致性。即系统(数据库)总是从一个一致性的状态转移到另一个一致性的状态,不会存在中间状态。
- I=Isolation,指的是隔离性。通常来说,一个事务在完全提交之前,对其他事务是不可见的。
- D=Durability,指的是持久性。一旦事务提交,那么就永远是这样子了,哪怕系统崩溃也不会影响结果。
32.事务是如何通过日志来实现的?
- 在Innodb存储引擎中,事务日志是通过redo和innodb的存储引擎日志缓冲(Innodb log buffer)来实现的。
- 当开始一个事务的时候,会记录该事务的lsn(log sequence number)号;
- 当事务执行时,会往InnoDB存储引擎的日志缓存里面插入事务日志;
- 当事务提交时,必须将存储引擎的日志缓冲写入磁盘(通过innodb_flush_log_at_trx_commit来控制),也就是写数据前,需要先写日志。这种方式称为“预写日志方式”,innodb通过此方式来保证事务的完整性。
- 也就意味着磁盘上存储的数据页和内存缓冲池上面的页是不同步的,是先写入redo log,然后写入data file,因此是一种异步的方式。
33. 同时有多个事务在进行会怎么样?
多事务的并发进行一般会造成以下几个问题:
- 更新丢失(Lost Update):当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题,最后的更新覆盖了由其他事务所做的更新;
- 脏读(Dirty Reads):一个事务正在对一条记录做修改,在这个事务没有提交前, 这条记录的数据就一直处于不确定状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些脏数据,并据此做进一步的处理,就会产生未提交的数据依赖关系,这种现象被形象地叫做脏读;
- 发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫做“不可重复读”;
- 幻读(Phantom Reads):一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读” 。
34. MySQL的事务隔离级别有哪些?
- 未提交读(READ UNCOMMITTED)。这个隔离级别下,其他事务可以看到本事务没有提交的部分修改,因此会造成脏读的问题(读取到了其他事务未提交的部分,而之后该事务进行了回滚);
- 已提交读(READ COMMITTED)。其他事务只能读取到本事务已经提交的部分,这个隔离级别有不可重复读的问题,在同一个事务内的两次读取,拿到的结果竟然不一样,因为另外一个事务对数据进行了修改;
- REPEATABLE READ(可重复读)。可重复读隔离级别解决了上面不可重复读的问题,但是仍然有一个新问题,就是幻读。当你读取id> 10 的数据行时,对涉及到的所有行加上了读锁,此时例外一个事务新插入了一条id=11的数据,因为是新插入的,所以不会触发上面的锁的排斥,那么进行本事务进行下一次的查询时会发现有一条id=11的数据,而上次的查询操作并没有获取到,再进行插入就会有主键冲突的问题;
- SERIALIZABLE(可串行化)。这是最高的隔离级别,可以解决上面提到的所有问题,因为他强制将所以的操作串行执行,这会导致并发性能极速下降,因此也不是很常用。
35. InnoDB使用的是哪种隔离级别?
InnoDB默认使用的是可重复读隔离级别。
36.REPEATABLE READ隔离级别下 MVCC 如何工作?
- SELECT:InnoDB会根据以下条件检查每一行记录:第一,InnoDB 只查找版本早于当前事务版本的数据行,这样可以确保事务读取的行要么是在开始事务之前已经存在要么是事务自身插入或者修改过的;第二,行的删除版本号要么未定义,要么大于当前事务版本号,这样可以确保事务读取到的行在事务开始之前未被删除。
- INSERT:InnoDB为新插入的每一行保存当前系统版本号作为行版本号。
- DELETE:InnoDB为删除的每一行保存当前系统版本号作为行删除标识。
- UPDATE:InnoDB为插入的一行新记录保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为删除标识保存这两个版本号,使大多数操作都不用加锁。它不足之处是每行记录都需要额外的存储空间,需要做更多的行检查工作和一些额外的维护工作。
37.InnoDB 如何开启手动提交事务?
InnoDB 默认是自动提交事务的,每一次 SQL 操作(非 select 操作)都会自动提交一个事务,如果要手动开启事务需要设置set autocommit=0禁止自动提交事务,相当于开启手动提交事务。
38.在 InnoDB 中设置了 autocommit=0,添加一条信息之后没有手动执行提交操作,请问这条信息可以被查到吗?
autocommit=0 表示禁止自动事务提交,在添加操作之后没有进行手动提交,默认情况下其他连接客户端是查询不到此条新增数据的。
更多 事务 相关精彩内容
5分钟搞懂MySQL事务隔离级别
面试被问Spring事务传播属性,绝对不能说不懂
一文读懂数据库事务
分析Spring是如何做事务事件监控的
分布式事务实战(含源码)
六、表结构设计相关
39. 为什么要尽量设定一个主键?
主键是数据库确保数据行在整张表唯一性的保障,即使业务上本张表没有主键,也建议添加一个自增长的ID列作为主键。设定了主键之后,在后续的删改查的时候会更加快速以及确保操作数据范围安全。
40. 主键使用自增ID还是UUID?
推荐使用自增ID,不要使用UUID。
因为在InnoDB存储引擎中,主键索引是作为聚簇索引存在的。也就是说,主键索引的B 树叶子节点上存储了主键索引以及全部的数据(按照顺序)。如果主键索引是自增ID,那么只需要不断向后排列即可;如果是UUID,由于到来的ID与原来的大小不确定,会造成非常多的数据插入,数据移动,然后导致产生很多的内存碎片,进而造成插入性能的下降。
总之,在数据量大一些的情况下,用自增ID性能会更好。
41. 字段为什么要求定义为not null?
MySQL官网这样介绍:
NULL columns require additional space in the rowto record whether their values are NULL. For MyISAM tables, each NULL columntakes one bit extra, rounded up to the nearest byte.
也就是:null值会占用更多的字节,且会在程序中造成很多与预期不符的情况。
七、优化相关
42.explain出来的各种item的意义是什么?
- select_type 。表示查询中每个select子句的类型;
- type。表示MySQL在表中找到所需行的方式,又称“访问类型”;
- possible_keys 。指出MySQL能使用哪个索引在表中找到行,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用;
- key。显示MySQL在查询中实际使用的索引,若没有使用索引,显示为NULL;
- key_len。表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度;
- ref。表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值 ;
- Extra。包含不适合在其他列中显示但十分重要的额外信息。
43.profile的意义以及使用场景有哪些?
Profile 用来分析 sql 性能的消耗分布情况。当用 explain 无法解决慢 SQL 的时候,需要用profile 来对 sql 进行更细致的分析,找出 sql 所花的时间大部分消耗在哪个部分,确认 sql的性能瓶颈。
44. 统计过慢查询吗?对慢查询都怎么优化过?
慢查询的优化首先要搞明白慢的原因是什么。是查询条件没有命中索引?是load了不需要的数据列?还是数据量太大?
所以优化也是针对这三个方向来的:
- 首先分析语句,看看是否load了额外的数据,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写;
- 分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者修改索引,使得语句可以尽可能的命中索引;
- 如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大,如果是的话可以进行横向或者纵向的分表。
45.说一说你能想到的sql语句优化,至少五种
- 避免select *,将需要查找的字段列出来;
- 使用连接(join)来代替子查询;
- 拆分大的delete或insert语句;
- 使用limit对查询结果的记录进行限定;
- 用 exists 代替 in 是一个好的选择;
- 用Where子句替换HAVING 子句,因为HAVING 只会在检索出所有记录之后才对结果集进行过滤;
- 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引尽量避免在where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描;
- 尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描;
- 尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
46.说一说你能想到的表结构优化,至少五种
- 永远为每张表设置一个ID;
- 选择正确的存储引擎 ;
- 使用可存下数据的最小的数据类型,整型 < date,time < char,varchar < blob;
- 使用简单的数据类型,整型比字符处理开销更小,因为字符串的比较更复杂。如,int类型存储时间类型,bigint类型转ip函数;
- 使用合理的字段属性长度,固定长度的表会更快。使用enum、char而不是varchar;
- 尽可能使用not null定义字段(给空字段设置默认值);
- 尽量少用text;
- 给频繁使用和查询的字段建立合适的索引。
更多 优化 相关精彩内容
开发人员必备的9大MySQL索引和查询优化
高级版MySQL优化方案
常见mysql的慢查询优化方式
一次生产的JVM优化
Java中的锁原理、锁优化、CAS、AQS,看这篇就对了!
八、其他
47.数据三大范式是什么?
- 第一范式( 1NF):字段具有原子性,不可再分。
- 第二范式( 2NF):是在第一范式( 1NF) 的基础上建立起来的,要求数据库表中的每个实例或行必须可以被惟一地区分。通常需要为表加上一个列, 以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键。
- 第三范式( 3NF):必须先满足第二范式( 2NF)。简而言之, 第三范式( 3NF) 要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。所以第三范式具有如下特征:1) 每一列只有一个值;2) 每一行都能区分;3) 每一个表都不包含其他表已经包含的非主关键字信息。
48.超大分页如何处理?
超大的分页一般从两个方向上来解决:
- 数据库层面,这也是我们主要集中关注的(虽然收效没那么大),类似于
select * from table where age > 20 limit 1000000,10
这种查询其实也是有可以优化的余地的。这条语句需要load1000000数据然后基本上全部丢弃,只取10条当然比较慢。当时我们可以修改为select * from table where id in (select id from table where age > 20 limit 1000000,10)
。这样虽然也load了一百万的数据,但是由于索引覆盖,要查询的所有字段都在索引中,所以速度会很快。同时如果ID连续的好,我们还可以select * from table where id > 1000000 limit 10
,效率也是不错的,优化的可能性有许多种,但是核心思想都一样,就是减少load的数据。 - 从需求的角度减少这种请求……主要是不做类似的需求(直接跳转到几百万页之后的具体某一页,只允许逐页查看或者按照给定的路线走,这样可预测,可缓存)以及防止ID泄漏且连续被人恶意攻击。
解决超大分页,其实主要是靠缓存,可预测性的提前查到内容,缓存至redis等k-V数据库中,直接返回即可。
49.MySQL数据库cpu飙升到500%的话,该如何处理?
- 多实例的服务器,先top查看是那一个进程占用CPU多;
- show processeslist 查看线程是否有锁住;
- 查看慢查询,找出执行时间长的sql;explain分析sql是否走索引,sql优化;
- 再查看是否缓存失效引起,需要查看buffer命中率。
50.什么是存储过程?
- 存储过程是一些预编译的SQL语句;
- 更加直白的理解:存储过程可以说是一个记录集,它是由一些T-SQL语句组成的代码块,这些T-SQL语句代码像一个方法一样实现一些功能(对单表或多表的增删改查),然后再给这个代码块取一个名字,在用到这个功能的时候调用他就行了;
- 存储过程是一个预编译的代码块,执行效率比较高,一个存储过程替代大量T_SQL语句 ,可以降低网络通信量,提高通信速率,可以一定程度上确保数据安全;
- 在互联网项目中,其实是不太推荐存储过程的,比较出名的就是阿里的《Java开发手册》中禁止使用存储过程。在互联网项目中,迭代太快,项目的生命周期也比较短,人员流动相比于传统的项目也更加频繁。在这样的情况下,存储过程的管理确实是没有那么方便,复用性也没有写在服务层那么好。
成功留给有准备的人,机遇留给准备好的人~~~大家继续加油呀!!!