联接查询优化

避免多表 Join(三张表及以上)

如果数据库的性能无限强大,多个表的 join 肯定是需要的,尤其是复杂的分析型(OLAP)查询,甚至可能涉及 10 几个表的 join,但现实是大部分数据库的性能都太弱了,尤其是涉及到多表 join 的查询。做这个限制有两个原因:一是优化器很弱,涉及多个表的查询,往往得不到很好的查询计划,二是执行器很弱,只有 nested loop join,block nested loop join 和 index nested loop join。

  • nested loop join 就是分别从两个表读一行数据进行两两对比,复杂度是 n^2。
  • block nested loop join 是分别从两个表读很多行数据,然后进行两两对比,复杂度也是 n^2,只是少了些函数调用等 overhead。
  • index nested loop join 是从第一个表读一行,然后在第二个表的索引中查找这个数据,索引是 B+树索引,复杂度可以近似认为是 nlogn,比上面两个好很多,这就是要保证关联字段有索引的原因。
  • 如果有 hash join,就不用做这种限制了,用第一个表(小表)建 hash table,第二个表在 hash table 中查找匹配的项,复杂度是 n。缺点是 hash table 占的内存可能会比较大,不过也有基于磁盘的 hash join,实现起来比较复杂。

可是我确实需要两个表里的数据链接在一起啊,我们可以做个冗余,建表的时候,就把这些列放在一个表里,比如一开始有 student(id, name),class(id, description),student_class(student_id, class_id)三张表,这样是符合数据库范式的(第一范式,第二范式,第三范式,BC 范式等),没有任何冗余,但是马上就不符合“编程规范“了,那我们可以用一张大表代替它,student_class_full(student_id, class_id, name, description),这样 name 和 description 可能要被存储多份,但是由于不需要 join 了,查询的性能就可以提高很多了。

上一页