北京JAVA基础面试30天打卡11
1.索引创建注意事项
适合的场景
1.频繁使用where语句查询的字段
2.关联字段需要建立索
3.如果不创建索引,那么在连接的过程中,每个值都会进行一次全表扫描
4.分组和排序字段可以建立索引因为索引天生就是有序的,在分组和排序时优势不言而喻
5.需要进行聚合统计的字段可以创建索引
6.比如需要对school字段进行count0操作:因
为B+树相同的值都存储在同一个叶子节点中统计速度很快但是并不是所有上诉的字段都可以建立索引,还需要考虑他是否是一下情况
不适合的场景
1.字段频繁的更新 因为频繁的更新除了修改表数据外还需要维护索引信息,B+树调整会降低性能
2.字段取值重复率高,区分度低唯一性差的字段不适合创建索引
3.比如性别字段,取值过于
·参与列计算的列不适合创建索引,索引会失效
2.MySQL中的索引数量是否越多越好?为什么?
因为索引不论从时间还是空间上都是有一定成本的
1)时间
每次对表中的数据进行增删改(NSERT、UPDATE或DELETE)的时候,索引也必须被更新,这会增加写入操作的开销。例如删除了一个name为面试鸭的记录,不仅主键索引上需要修改,如果name字段有索引,那么name索引也需要修改,所以索引越多需要®改的地方也就越多,时间开销就大了,并且B+树可能会有页分裂、合并等操作,时间开销就会更大。
还有一点需要注意:小ySQL有个查询优化器,它需要分析当前的查询,选择最优的计划,这过程就需要考虑选择明那个索引的查询成本低。如果索引过多,那么会导致优化器耗费更多的时间在选择上,甚至可能因为数据的不准确而选择了次优的索引。
2)空间
每建立一个二级索引,都需要新建一个B+树,默认每个数据页都是16KB,如果数据量很大,索引又很多,占用的空间可不小。
3.MySQL中如何进行SQL调优?
1.避免select*,只查询必要的字段
2.合理设计索引,通过联合索引进行覆盖索引及索引下推技术的优化,减少回表的次数,提升效率
3.避免SQL中进行函数计算等操作,导致无法命中索引
4.避免使用like,导致全表扫描(如果符合最左前缀匹配原则可以走索引)】
5.注意使用联合索引需满足最左匹配原则
6.不要对无索引字段进行排序操作
7.连表查询需注意不同字段的字符集保持一致
8.注意隐式类型转换操作,会导致索引失效使用OR,两边需保持等值匹配且都为索引列,才会走索引
以上都是对SQL进行优化,避免索引失效等进行SQL调优,还可以从其他方面进行考虑,比如先分析SQL慢的原因
-索引失效
-多表oin
-查询字段太多
-表中数据量太大
-索引区分度不高
-数据库连接数不够
-数据库的表结构不合理
-数据库IO或者CPU比较高
-数据库参数不合理
-长事务导致的
-锁竞争导致的长时间的等待
拓展:
1:为什么多表join会导致SQL慢?
MySQL是使用了嵌套循环(Nested.-Loop Join)】的方式来实现关联查询的,简单点说就是要通过两层循环,用第一张表做外循环,第二张表做内循环,外循环的每一条记录跟内循环中的记录作比较,符合条件的就输出。而具体到算法实现上主要有simple nested loopblock nested loop和index nested loop这三种。而且这三种的效率都没有特别高。小ySQL是使用了嵌套循环(Nested-Loop Join)的方式来实现关联查询的,如果有2张表join的话,复杂度最高是0(n2),3张表则足0n3)随着表越多,表中的数据量越多,JOIN的效率会呈指数级下降。
2:不使用引oin,如何做关联查询?
主要有以下做法
1、在内存中自己做关联,即先从数据库中把数据查出来之后,我们在代码中再进行二次查询,然后再进行关联。
2、数据冗余,那就是把一些重要的数据在表中做冗余,这样就可以避免关联查询了。
3、宽表,就是基于一定的join关系,把数据库中多张表的数据打平做一张大宽表,可以同步到ES或者干脆直接在数据库中直接查都可以
3.数据量太大也会导致SQL慢,那怎么解决?
具体的解决方案有以下几种:
1、数据归档,把历史数据移出去,比如只保留最近半年的数据,半年前的数据做归档。
2、分库分表、分区。把数据拆分开,分散到多个地方去,这里不详细介绍了,我们的文档中有分库分表和分区的详细介绍,不展开了。
3、使用第三方的数据库,比如把数据同步到支持大数量查询的分布式数据库中,如oceanbase、