问题一:MySQL有张表每天新增数据百万,需要导出一个月的数据,请问如何快速导出呢?

分析:每个月3千万的数据,1年3.6亿。随着时间推移,数据快速膨胀。

方案:

1. 数据增速很快,假如我们是按自然月导出的话,我们可以按月分表,一个月一张表。避免表数据量膨胀后影响查询速度。
2. 如果按自然月计算,我们可以考虑提前计算。比如凌晨开始执行导出逻辑,等白天一觉醒来已经完成导出了。
3. 如果想缩短时间,可以考虑分片。比如:分多个线程(甚至可以多台机器),每个线程导出一部分数据(这里需要注意数据量级和处理方式,避免把大量的数据加载到内存中频繁以新发fullgc甚至oom)。所有线程动作处理完成后,执行合并文件动作。
4. 导出Excel的话,Excel其实是个压缩包,如果使用POI写的太慢,可以考虑安装Excel的规范写内容,自己打包后修改后缀,改为Excel的后缀。

问题二:复合索引如何理解?

可以这样简单理解复合索引,想象这个表有一个字段,这个字段是符合索引中几个字段的组合,然后使用这个字段作为索引,这个索引的效果就和符合索引的效果类似。

问题三:复合索引在使用时遵循最左前缀原则,这是基于什么原理呢?

复合索引最左匹配,其实单个索引也是最左匹配的。

innodb的B+树是一棵有序树,怎么比较两个字符串的大小呢?是从最左边的字符开始一个一个的比较的。当我们拿一个条件去索引中查询的时候,本质上就是一个两两的比较,从树根开始一直定位到最终的叶子节点。如果我们的查询条件是 like '%xxx',很明显数据库时无法利用索引进行比较的,因为左边是缺失的,而比较是从左边开始比较的。必须是like 'xxx%'这种的,数据库才可以进行比较。一个复合索引index(a_b_c),如果用a字段去查询,可以利用索引,如果使用b或者c字段查询就无法利用索引。

问题四:innodb有两种索引,b+ tree和hash,hash索引还遵循最左匹配吗?

hash索引是精确匹配,经过hash之后的数据已经和原数据没关系了,只能进行精确匹配查询,无法使用最左匹配。

innodb引擎是不能人工去设置hash索引的,innodb内部的优化机制有自适应哈希索引。我们平常使用的Navicat里面有设置hash索引的地方,如下图

这里设置hash索引的是不生效的。不信的话更详细的可以看 Mysql 的InnoDB引擎下支持hash索引吗?

问题五:关于数据库并发访问量过大的导致数据库压力过大的问题,常见的解决方案有哪些呢?

对于一个系统来说,数据库是很难水平扩展的,成本很高。因此系统的瓶颈往往在于数据库。当访问量非常高时,我们需要尽量减少流量进入数据库中去。常见的做法是把数据缓存起来,下一次访问的时候直接从缓存中读取,而不是访问数据库,以减少数据库的压力。这种做法一般适用于读多写少的场景,对于写比较多的场景,我们通常采用异步化(比如消息队列)、分片进行处理等操作。

问题六:一张表查询只会用到一个索引,对吗?

select * from user where sex="F" and area="beijing" order by date desc limit 100

对于这条SQL,我们最优解是建立sex、area、date三个字段的组合索引,先后顺序也不能变,如此这三个字段的索引才能用上。如果我们分别建立sex、area、date三个索引的话,那么最终只会用到其中一个索引,其他两个不会用到。选择什么索引不是根据先后顺序,而是数据库引擎会估算使用哪个索引的效率比较高优先选择哪个。

问题七:实际场景中对于事务的操作,是否是必须的?是否存在为了效率可以用代码控制而舍弃数据库本身的事务控制的场景呢?

如果需要事务,最好加上事务,否则脏数据比较麻烦。在使用事务的基础上,尽量避免长事务,因为长事务比较耗时,在并发量比较高的情况下,会有锁等待的问题。对于长事务,考虑将流程做拆解。

问题八:电商场景中防止“超卖”常见使用的预扣库存的解决方案,具体是如何做的呢?

在不考虑高并发的情景下,对于每一件商品,我们可以设计库存相关的两个字段,一个是剩余库存,另一个是可用剩余库存。再增加一张预扣记录表,在预扣记录表中记录支付超时的时间。当下单成功先减可用剩余库存,然后写预扣记录表,支付完成之后再减去剩余库存。如果超时还未完成支付,则将可用剩余库存进行还原,还原为未减之前的状态。

核心思想:预扣的时候减可用剩余库存,实扣的时候减剩余库存。

实际高并发的场景中,我们可以在缓存(比如Redis)中做这个预扣的操作,实扣的时候再去数据库里扣。

问题九:不是主从架构的两个库的数据实时保持同步,应该怎么做?

可以考虑利用canal监听binlog来做增量同步。canal入门知识可以参考 超详细的Canal入门,看这篇就够了!

问题十:Nginx负载均衡到多台服务器,其中一台宕机怎么办?

Nginx自己有检测机制,会自动把有问题的剔除掉。