文章之前的描述存在不少问题,今天重新改写了些内容。
开篇之前还是先来回顾一下这个错误的MySQL优化案例:
开发同学期望将两个表的数据汇集之后,取满足条件的top N,于是使用union all联合两个结果集,最后使用limit取top 30。两个表的数据量接近500w,执行耗时12.66秒:
整体来看,性能比较差,下面这种优化是期望将limit推入到两个联合的子句中来减少联合对性能影响,执行耗时在0.03秒,效果还不错。
但这里用到的优化思路看起来好像没有问题,但逻辑的实现是有问题的,而且改写前原SQL的逻辑也是存在问题的,具体是什么问题,看完下面的实验之后,相信也就自然明白了。
下面我们通过PostgreSQL来演示一下这里埋的是什么坑。MySQL和Oracle应该也是一样的效果。时间有限,就不做过多对比了。
先来创建两个测试表:
akendb=# \d+ tab01 Table "public.tab01" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description -----------+---------+-----------+----------+---------+---------+--------------+------------- id | integer | | not null | 0 | plain | | num_col01 | integer | | not null | 0 | plain | | akendb=# \d+ tab02 Table "public.tab02" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description -----------+---------+-----------+----------+---------+---------+--------------+------------- id | integer | | not null | 0 | plain | | num_col01 | integer | | not null | 0 | plain | | akendb=#
然后每张表简单插入3行数据即可: