一.单表数据量大当起始页很后面的时候查询会变的很慢这时候应该怎么处理。
方案一:
select * from (SELECT ID FROM where 条件 ....)先用查询将id查询出来。原理是因 select * 的时候会将前面每行数据进行扫描,查询出来只有id的情况即只扫描条件字段,当字段多查询条件少的时候在45万数据查询最后200条的情况下会节省3倍时间。
方案二:
场景单一, 顺序查询,固定分页的情况下,根据 ID, 时间 排序 查询每次将当前页的最后数据 作为下次查询的 条件 如: 表 tb, 里面数据有 id 1~10000 每次查询200条
第一次查询 : SELECT * FROM tb WHERE id >0 LIMIT 200
第二次查询 : SELECT * FROM tb WHERE id >200 LIMIT 200
第三次次查询 : SELECT * FROM tb WHERE id >400 LIMIT 200
二. MyBatis xml 条件标签里参数字符串字段判断数字值的时候 如: <if test ="typeStr !=null and typeStr == '1'"> 条件不生效
方案 : 改为: <if test =' typeStr !=null and typeStr == "1" '> 原理: " 双引号的条件里面值为数字字符串时会先转换成数字 然后再做比较
三. 在插入数据的时候业务判断数据是否存在如果存在就更新怎么原子操作
INSERT IGNORE INTO names(name,age) VALUES('王五',22)
ON DUPLICATE KEY UPDATE //根据插入的时候已经触发唯一索引去执行下列的update
name = VALUES(name),
age = 35
VALUES() 是针对同时插入多条记录时获取正确的待设置值 应该在插入单行的时候使用VALUES,在插入多行的时候使用VALUE
四.如何让 逻辑删除 和 唯一索引 的一起使用
1表USER , 字段 ID, NAME, PHONE, IS_DELETED
方案一:
这时需要 唯一索引设置 PHONE,IS_DELETED
当一行数据被删除的时候将 IS_DELETED 值设置为 NULL,默认插入时设置为 0
这时即可插入同样 PHONE 的数据 (同数据需要逻辑回复业务关联老数据时场景不可使用)
五. 唯一复合索引 顺序搞乱会导致索引失效
场景说明: 1表USER , 字段 ID, AA, BB, CC,IS_DELETED
方案一:
这时业务需要 唯一索引设置 BB, CC, IS_DELETED
在 WHERE 条件里面 IS_DELETED = 0 AND CC = 2 发现索引不生效
原理:实际上在数据库里面会有 BB | BB, CC | BB, CC,IS_DELETED 三个索引被创建
场景为以下三种:
1. CC = ? AND BB =? 会用到第一个索引,
2. CC=? AND BB = ? MySql会自动排序 满足第二个索引,
3. CC=? AND IS_DELETED = ? 没有满足的索引他的执行type = ALL
新版的Mysql 已经解决了这个问题:
1.顺序不会影响索引的使用,
2.缺少后面,的字段不会影响索引的使用,缺少前面的字段会有影响
3.如果不用AND 使用例如 order by 或者 Or 等是不会触发索引的,另外,order by 单个BB是可以触发索引的。
六. 当应用内实体表对象过多,tddl 分库分表数据库连接工具启动过慢优化思路
我们的一个老项目里面有98张表, 每次启动服务器需要10来分钟,看不下去的我决定优化一下,通过日志发现 tddl 的初始化占用了将近2分多钟
于是我仔细排查启动日志 发现 tddl 初始化的步骤如下:
第一步 从domaind 获取配置,初始化 SqlSessionTemplate
第二步 拉取每张表的分表表名及路由规则 “tb_XX_0000,tb_XX_0001,tb_XX_0002,tb_XX_0003”
第三步 拉取每张表的 在配置的 group0 ~ group8 (项目自己配置的) 最多8此去select 定位当前的全局唯一SequenceID (耗时最厉害的步骤)
第四步 在插入时,通过 innerStep 配置的数量 获取一批量id VALUE 设置过少 会导致id 获取冲突
从上面流程不难看出其实可以通过懒加载去实现初始化的过程提高启动速度,比如:
但是发现在beans和 bean 上面加入配置 lazy-init = true 也不会生效。最终仔细排查发现在DAO里面通过@Autowired 去加载了该bean 从而让懒加载配置无效,最终只得写一个SequenceUtils 去springContext 里面去获取对应的Sequence 对象实现懒加载。