or索引:
where 语句里面如果带有or条件, myisam表能用到索引, innodb不行
使用or的列必须都有独立单列索引,否则索引失效,造成全表扫描
使用union来代替or索引
排序:
所排序数组的数值在一定范围内使用桶排序
乐观锁,悲观锁:
乐观锁是是认为当前数据没有被别人修改,但是在更新的时候回去判断一下值有没有被修改,使用于多读的应用场景。
悲观锁是每次访问数据时都会认为别人会修改数据,所以会对数据加锁,被人想访问数据就必须阻塞到它获得锁。
java中的悲观锁是用synchronize关键字来实现,数据库中则行锁和表锁,读锁,写锁
Java中的乐观锁是使用cas来实现,数据库则是使用多版本MVVM来实现
cas缺点:
ABA问题,线程1获取A,线程2将A改成B,然后再改成A,线程1执行,并不知道已发生过改变。
例子:单链表问题
自旋时间过长开销大
只能保证一个共享变量的操作,如果要操作多个共享变量可以将他们封装为对象
synchronize缺点:
一个线程持有锁会导致其他线程发生阻塞,加锁,释放锁会导致大量的上下文切换和性能开销
cas和synchronize使用场景:
对于资源竞争线程比较少的时候,使用synchronize对资源上锁,会导致阻塞和唤醒切换以及用户态和内核态的切换,会消耗额外的cpu资源,而cas的实现基于硬件,不会需要进入内核和切换线程,自旋的几率也比较小,可以获得较高的性能。
在资源竞争比较激烈的时候,cas自旋的概率就比较大,浪费的资源就比较过,所以性能比synchronize要差
jvm在堆中分配内存:
单线程:
1、指针碰撞,在内存比较规整的情况下(取决于内存的回收策略),分配内存的工作只是将指针移动对象大小的距离即可
2、table
适用于内存不规整的情况下,jvm维护了一个空闲内存的列表,记录了空闲内存的地址和大小,分配内存的时候去列表中查询合适的区域即可
多线程:
由于给对象分配内存时的操作不是原子性的,过程包含查询空闲列表,分配内存,修改空闲类表等等,所以操作是非线程安全的。
解决办法:
1、cas,失败时重试
2、TLAB:jvm事先先给每个线程分配一个缓冲区,在里面给对象进行内存分配,当对象的大小超过这个缓冲区的时候,再使用cas对对象进行分配内存
innodb的聚集索引:
主键索引的叶子节点data保存的是表的数据,mylsam保存的是数据的地址
辅助索引d的叶子节点保存的是主键的值,然后再通过主键索引回表寻找数据。
如果select的列有设置索引可以避免回表查询数据,所以尽量少使用select * 查询频率比较高的列可以设置索引
在mysql中执行查询时,只能使用一个索引,如果我们在每个列分别建索引,执行查询时,只能使用一个索引,mysql会选择一个最严格(获得结果集记录数最少)的索引。所以当使用where和order by的时候,如果是两个不同的索引,则order by不会使用索引
组合索引:
理论上索引对顺序是敏感的,但是mysql会根据情况对列的顺序做出调整,调整成你所设置的索引,所以顺序不影响索引的使用,索引使用要遵守最左匹配原则,带头大哥不能丢,中间小弟不能断,使用最频繁的类放在第一列。
索引不包含nul值得列,并不是说有null值得列就不走索引,而是使用is null 来判断列是否为null值得时候,索引失效??,因为索引不存储null值。
当创建了唯一索引的列,空值是会被当做重复的值导致插入失败,而null值就不会,可以重复插入,null值是占空间的
导致内存溢出的原因:
存在死循环,或者循环过大生成新对象太多
内存泄漏,集合中还保存着对象引用,使用完后没有清空,不能被回收
内存一次性加载数据过多,如一次性从数据库中取太多数据
启动参数内存值设定过小
内存溢出类型:
解决:
修改启动内存参数,jvm默认为64M,tomcat默认为128M,使用-xms,-xmx设置,一般上线时,-xmx=-xms,防止内存抖动(当jvm可用内存低于40%时,jvm会自动增加内存村,直到达到xmx,当可用内存超过70%时,jvm会减少内存,直到-xms)
代码排查,对是否存在死循环或者大循环进行排查
是否有一次性加载大量数据的操作
判断是否有集合使用完对象没有置空的情况