join的性能问题
MySQL是使用了嵌套循环(Nested-Loop Join)的方式来实现关联查询的,简单点说就是要通过两层循环,用第一张表做外循环,第二张表做内循环,外循环的每一条记录跟内循环中的记录作比较,符合条件的就输出。 如果有2张表join的话,复杂度最高是O(n^2),3张表则是O(n^3)…随着表越多,表中的数据量越多,JOIN的效率会呈指数级下降。
在内存中自己做关联
在代码中进行两次循环
拿到2张表的全量数据, 直接2个循环进行遍历,当然性能也差,还有可能造成oom,但减轻了数据库的压力。
在代码中用哈希表优化
用一个 hashMap存储较小的tb2表,使用主键id列当作哈希表的key,只对大表做for循环。
for (row r1 : tb1) {
if(idMap.containKey(r1.getId())) {
row r2 = idMap.get(r1.getId());
r3 = join(r1,r2)
result.add(r3)
}
}
复杂度就优化到了O(n),当然还是有可能oom 。
数据冗余
数据冗余,那就是把两张表的重要字段在各自表中做冗余,避免关联查询了。
宽表
把数据库中多张表的数据打平做一张大宽表,可以同步到ES或者干脆直接在数据库中直接查都可以