记一次长达4s的sql
- 表a a_id xxxx
- 表b b_id a_id xxxx
- 表c c_id a_id xxx
- 表d 表e 表xxx
其中表a位主表,表a与 表b 和表c 一对多
,而表d,e和xxx,一一对应!
sql:
select *
from a
left join b on a.a_id = b.a_id
left join c on a.a_id = c.a_id
left join d on a.a_id = d.a_id
left join e on a.a_id = e.a_id
XXXX
虽然数据是正确的,但是执行了4s 最后得到一个!而且我看了下,数据量还属于小表的范围!!
想了半天最后终于找到原因了,很简单的原理,就是顺序错了,或者因为我的顺序,极大的增加了mysql的计算量
假如 abe 一 一对应
a == 100条数据
b == 20条数据
e == 30条数据
我们比较两种顺序
1.a和b通过笛卡尔积 形成虚表tb1 , b和e 在形成tb2
2.a和e.... 形成tb1,e和b形成tb2
我们计算比较次数,一次比较为一次
1. a和b ⇒ 100 * 20 ;tb1和e ⇒ 100 * 30
2. a和e ⇒ 100 * 30 ;tb1和b ⇒ 100 * 20
以上说明 一 一 对应的情况下
那么 不是一 一对应 比如 b和a的关系是一对多?
1.a和b ⇒ 100 * 20 ; tb1和e ⇒ >100 * 30
2.a和e ⇒ 100 * 30 ; tb1和b ⇒ 100 * 20
发现了吗?
由于a和b 不是一一对应,那么最后的结果将生成多条记录
这个时候 计算量就开始爆炸了!!!
最后得出结论, 写sql尽可能的避免一对多的情况,如果非要做统计之类的事情,我们可以left join (select xxxx) 这样来统计!!
表达能力有点差哈! 看不懂的请跳过,看懂的,请开喷!