方案一:
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 条件标签里参数字符串字段判断数字值的时候 如: 方案 : 改为:
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
六. 当应用内实体表对象过多,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 对象实现懒加载。



