如何做自己的加盟网站,梁志天设计公司考题,网站关键词多少个字数 站长网,网站网站开发设计主博客#xff1a;
【MySQL精通之路】SQL优化(1)-查询优化-CSDN博客
上一篇#xff1a;
【MySQL精通之路】SQL优化(1)-查询优化(9)-外部联接优化-CSDN博客
下一篇#xff1a;
【MySQL精通之路】SQL优化(1)-查询优化(11)-多范围查询优化-CSDN博客 查询时FROM子句中的表达…主博客
【MySQL精通之路】SQL优化(1)-查询优化-CSDN博客
上一篇
【MySQL精通之路】SQL优化(1)-查询优化(9)-外部联接优化-CSDN博客
下一篇
【MySQL精通之路】SQL优化(1)-查询优化(11)-多范围查询优化-CSDN博客 查询时FROM子句中的表达式在许多情况下都得到了简化。
在解析器阶段具有右外部联接操作的查询被转换为仅包含左联接操作的等效查询。
在一般情况下执行转换时此右联接
(T1, ...) RIGHT JOIN (T2, ...) ON P(T1, ..., T2, ...) 成为此等效的左联接
(T2, ...) LEFT JOIN (T1, ...) ON P(T1, ..., T2, ...)
形式为T1 inner join T2 ON PT1T2的所有内部联接表达式被作为联接到WHERE条件或嵌入联接的联接条件如果有的话表达式 T1T2PT1、T2所代替。
当优化器评估外部联接操作的计划时它只考虑这样的计划即对于每个这样的操作外部表在内部表之前被访问。优化器的选择是有限的因为只有这样的计划才能使用嵌套循环算法执行外部联接。
考虑这种形式的查询其中RT2极大地缩小了表T2中匹配行的数量
SELECT * T1 FROM T1LEFT JOIN T2 ON P1(T1,T2)WHERE P(T1,T2) AND R(T2)
如果按写入的方式执行查询则优化器别无选择只能在更受限制的表T2之前访问限制较少的表T1这可能会产生非常低效的执行计划。
相反如果拒绝WHERE条件为nullMySQL会将查询转换为不包含外部联接操作的查询。也就是说它将外部联接转换为内部联接。如果为外部联接操作生成的任何NULL补齐行的条件计算结果为FALSE或UNKNOWN则称该条件为NULL拒绝。
因此对于这种外部连接
T1 LEFT JOIN T2 ON T1.AT2.A 此类条件被拒绝为null因为它们对于任何NULL补齐行T2列设置为null都不能为true
T2.B IS NOT NULL
T2.B 3
T2.C T1.C
T2.B 2 OR T2.C 1 这样的条件不会被NULL拒绝因为它们对于NULL补齐行可能为true
T2.B IS NULL
T1.B 3 OR T2.B IS NOT NULL
T1.B 3 OR T2.B 3 检查条件是否为null的一般规则对于外部联接操作是拒绝的这些规则很简单 1.它的形式为A IS NOT NULL其中A是任何内部表的属性 2.它是一个断言包含对内部表的引用当其中一个参数为NULL时该表的计算结果为UNKNOWN 3.它是一个连词包含一个空拒绝条件作为连词 4.它是空拒绝条件的变体 对于查询中的一个外部联接操作条件可以为NULL拒绝而对于另一个条件不能为NULL拒绝。在这个查询中WHERE条件对于第二个外部联接操作是NULL拒绝的但是对于第一个操作不是NULL拒绝的
SELECT * FROM T1 LEFT JOIN T2 ON T2.AT1.ALEFT JOIN T3 ON T3.BT1.BWHERE T3.C 0
如果查询中的外部联接操作拒绝WHERE条件为null则外部联接操作将替换为内部联接操作。
例如在前面的查询中第二个外部联接被null拒绝可以用内部联接代替
SELECT * FROM T1 LEFT JOIN T2 ON T2.AT1.AINNER JOIN T3 ON T3.BT1.BWHERE T3.C 0 对于原始查询优化器仅评估与单表访问顺序T1、T2、T3兼容的计划。对于重写的查询它另外考虑访问顺序T3、T1、T2。
一个外部联接操作的转换可能会触发另一个的转换。因此查询
SELECT * FROM T1 LEFT JOIN T2 ON T2.AT1.ALEFT JOIN T3 ON T3.BT2.BWHERE T3.C 0 首先转换为查询
SELECT * FROM T1 LEFT JOIN T2 ON T2.AT1.AINNER JOIN T3 ON T3.BT2.BWHERE T3.C 0 这相当于查询
SELECT * FROM (T1 LEFT JOIN T2 ON T2.AT1.A), T3WHERE T3.C 0 AND T3.BT2.B 剩余的外部联接操作也可以由内部联接代替因为条件T3.BT2.B为空被拒绝。这将导致一个根本没有外部联接的查询
SELECT * FROM (T1 INNER JOIN T2 ON T2.AT1.A), T3WHERE T3.C 0 AND T3.BT2.B 有时优化器成功地替换了嵌入的外部联接操作但无法转换嵌入的外部连接。以下查询
SELECT * FROM T1 LEFT JOIN(T2 LEFT JOIN T3 ON T3.BT2.B)ON T2.AT1.AWHERE T3.C 0 转换为
SELECT * FROM T1 LEFT JOIN(T2 INNER JOIN T3 ON T3.BT2.B)ON T2.AT1.AWHERE T3.C 0 只能重写为仍包含嵌入外部联接操作的形式
SELECT * FROM T1 LEFT JOIN(T2,T3)ON (T2.AT1.A AND T3.BT2.B)WHERE T3.C 0
任何转换查询中嵌入外部联接操作的尝试都必须将嵌入外部联接的联接条件与WHERE条件一起考虑在内。在该查询中嵌入的外部联接的WHERE条件不是null拒绝而是嵌入的外部连接的联接条件T2.AT1.A AND T3.CT1.C是null拒绝
SELECT * FROM T1 LEFT JOIN(T2 LEFT JOIN T3 ON T3.BT2.B)ON T2.AT1.A AND T3.CT1.CWHERE T3.D 0 OR T1.D 0 因此查询可以转换为
SELECT * FROM T1 LEFT JOIN(T2, T3)ON T2.AT1.A AND T3.CT1.C AND T3.BT2.BWHERE T3.D 0 OR T1.D 0