Left join优化规则的研究

来源:互联网 发布:淘宝仓库发货流程 编辑:程序博客网 时间:2024/06/05 00:10

对于left join的优化,是应用开发人员、数据库内核开发人员关注的问题之一。我当初对left join进行分析归纳,后来阅读mysql时发现sql_select.cpp文件中的simplify_joins()函数的实现方法也是这样的,大家可以参考该函数。

  【IT专家网独家】一、概述

  对于left join的优化,是应用开发人员、数据库内核开发人员关注的问题之一。

  应用开发人员关注是因为:并不是每个数据库的内核都支持left join的内部转化,这时候需要应用开发人员进行手工地转化。

  内核开发人员关注是因为:并不假定每个应用开发人员都能够熟练地将left join转化掉。因此数据库有必要对这种情况,进行数据库内部的优化。

  我当初对left join进行分析归纳,后来阅读mysql时发现sql_select.cpp文件中的simplify_joins()函数的实现方法也是这样的,大家可以参考该函数。

  二、left join优化规则的研究

  t1 left t2 on t1.col1=t2.col1

  对于类似的表达式,在什么样的情况下才可以去掉left join呢?

  我们首先创建三张表:

  create table t1(c1 int,c2 int);

  create table t2(d1 int,d2 int);

  create table t3(e1 int,e2 int);

  2.1 优化的基本策略

  对于left join的查询语句,比如:

  select * from t1 left join t2 on t1.c1=t2.d2 where condition1 [{and conditonN}];(N的取值为2,3,……) (语句1)

  什么情况下,才能优化为语句:

  select * from t1 inner join t2 on on t1.c1=t2.d2 where condition1 [{and conditonN}]; (语句2)

  备注:语句2等价于语句:

  select * from t1,t2 where t1.c1=t2.d2 and condition1 [{and conditonN}]; (语句3)

  回答:

  只要where中的至少有一个conditionK(N的取值为1,2,……)满足如下非NULL条件,就可以将语句1优化为语句2(语句3):

  1)conditionK包含t2表的列(任意列)

  2)conditionK的类型只要不为: t2.column is null。

  其它的任何类型都行:比如t2.d2=t1.c2,再比如t2.d2 is not null。

  例1:

  select * from t1 left join t2 on t1.c1=t2.d2 where t2.d1=2; (t2.d1=2满足非NULL条件,可以优化)

  <==>等价于: select * from t1 inner join t2 on t1.c1=t2.d2 where t2.d1=2;

  <==>等价于: select * from t1,t2 where t1.c1=t2.d2 and t2.d1=2;

  例2:select * from t1 left join t2 on t1.c1=t2.d2 where t2.d1+1>t1.c1; (t2.d1+1>t1.c1满足非NULL条件,可以优化)

  <==>等价于: select * from t1 inner join t2 on t1.c1=t2.d2 where t2.d1+1>t1.c1;

  <==>等价于: select * from t1,t2 where t1.c1=t2.d2 and t2.d1+1>t1.c1;

  2.2思路扩展

  a left join b on condition1 {and conditionM}

  left join c on contion2_1 {and contion2_N}

  --优化的思路和上文提出的观点完全一样。

  例3:

  select * from t1 left join t2 on c1=d1 left join t3 on d2=e1 where e1=1; (e1满足非NULL条件,可以优化,甚至这里可以为:e2 in (select ……))

  <==>等价于:select * from t1 left join t2 on c1=d1 inner join t3 on d2=e1 where e1=1; //inner转换

  <==>等价于:select * from t1 left join t2 on c1=d1,t3 where d2=e1 and e1=1; //等价调整,然后(d2=e1满足非NULL条件,可以优化)

  <==>等价于:select * from t1 inner join t2 on c1=d1,t3 where d2=e1 and e1=1; //inner转换

  <==>等价于:select * from t1,t2,t3 where c1=d1 and d2=e1 and e1=1;