1.正常的连接
2.使用缓存的连接
3.内连接的顺序性,优化程序可对其顺序进行优化,谓词的下沉,先根据其中子句中的条件(最左边的)过滤再进入到内层的表进行匹配。
4.外连接,优化程序不会对其进行优化,完全按照程序员写的顺序进行连接。先匹配行,对根据其中子句中的条件进行判断。
5.内链接可以优化为内链接,(如果表1外连接表2,对于表2中的字段设为null,一次来匹配表1,对于这些行,如果经where子句判断后均为 false,说明这些行对结果均无作用,这种情况下,外连接与内链接的结果相同)。外连接
优化为内链接后,表1,表2的连接顺序可以被优化程序所改变。例如:
For a LEFT JOIN
, if the WHERE
condition is always false for the generated NULL
row, the LEFT JOIN
is changed to an inner join. For example, theWHERE
clause would be false in the following query if t2.column1
were NULL
:
SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5;
Therefore, it is safe to convert the query to an inner join:
SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1;
Now the optimizer can use table t2
before table t1
if doing so would result in a better query plan.
下面这段内容是关于3,4的详细讲解,未完全看明白...
在讨论内部联接的嵌套循环算法时,我们省略了一些细节,这些细节对查询执行性能的影响可能很大。我们没有提到所谓的 “ 推倒 ” 条件。假设我们的 WHERE
条件 P(T1,T2,T3)
可以用一个联合公式表示:
P(T1,T2,T2) = C1(T1) AND C2(T2) AND C3(T3).
在这种情况下,MySQL实际上使用以下嵌套循环算法来执行带有内连接的查询:
FOR each row t1 in T1 such that C1(t1) {
FOR each row t2 in T2 such that P1(t1,t2) AND C2(t2) {
FOR each row t3 in T3 such that P2(t2,t3) AND C3(t3) {
IF P(t1,t2,t3) {
t:=t1||t2||t3; OUTPUT t;
}
}
}
}
你看,每个合取的 C1(T1)
, C2(T2)
, C3(T3)
是最内环的推到最外环的地方进行评估。如果 C1(T1)
是一个非常严格的条件,这个条件下推可能会大大减少从T1
传递给内循环的表的行数 。结果,查询的执行时间可能会大大改善。
对于具有外连接的查询, WHERE
仅在发现外部表中的当前行在内部表中具有匹配项之后才检查条件。因此,从内部嵌套循环中推出条件的优化不能直接应用于具有外部联接的查询。这里我们必须引入条件下推谓词,这些谓词由遇到匹配时打开的标志保护。
在讨论内部联接的嵌套循环算法时,我们省略了一些细节,这些细节对查询执行性能的影响可能很大。我们没有提到所谓的 “ 推倒 ” 条件。假设我们的 WHERE
条件 P(T1,T2,T3)
可以用一个联合公式表示:
P(T1,T2,T2) = C1(T1) AND C2(T2) AND C3(T3).
在这种情况下,MySQL实际上使用以下嵌套循环算法来执行带有内连接的查询:
FOR each row t1 in T1 such that C1(t1) {
FOR each row t2 in T2 such that P1(t1,t2) AND C2(t2) {
FOR each row t3 in T3 such that P2(t2,t3) AND C3(t3) {
IF P(t1,t2,t3) {
t:=t1||t2||t3; OUTPUT t;
}
}
}
}
你看,每个合取的 C1(T1)
, C2(T2)
, C3(T3)
是最内环的推到最外环的地方进行评估。如果 C1(T1)
是一个非常严格的条件,这个条件下推可能会大大减少从T1
传递给内循环的表的行数 。结果,查询的执行时间可能会大大改善。
对于具有外连接的查询, WHERE
仅在发现外部表中的当前行在内部表中具有匹配项之后才检查条件。因此,从内部嵌套循环中推出条件的优化不能直接应用于具有外部联接的查询。这里我们必须引入条件下推谓词,这些谓词由遇到匹配时打开的标志保护。
在讨论内部联接的嵌套循环算法时,我们省略了一些细节,这些细节对查询执行性能的影响可能很大。我们没有提到所谓的 “ 推倒 ” 条件。假设我们的 WHERE
条件 P(T1,T2,T3)
可以用一个联合公式表示:
P(T1,T2,T2) = C1(T1) AND C2(T2) AND C3(T3).
在这种情况下,MySQL实际上使用以下嵌套循环算法来执行带有内连接的查询:
FOR each row t1 in T1 such that C1(t1) {
FOR each row t2 in T2 such that P1(t1,t2) AND C2(t2) {
FOR each row t3 in T3 such that P2(t2,t3) AND C3(t3) {
IF P(t1,t2,t3) {
t:=t1||t2||t3; OUTPUT t;
}
}
}
}
你看,每个合取的 C1(T1)
, C2(T2)
, C3(T3)
是最内环的推到最外环的地方进行评估。如果 C1(T1)
是一个非常严格的条件,这个条件下推可能会大大减少从T1
传递给内循环的表的行数 。结果,查询的执行时间可能会大大改善。
对于具有外连接的查询, WHERE
仅在发现外部表中的当前行在内部表中具有匹配项之后才检查条件。因此,从内部嵌套循环中推出条件的优化不能直接应用于具有外部联接的查询。这里我们必须引入条件下推谓词,这些谓词由遇到匹配时打开的标志保护。
在讨论内部联接的嵌套循环算法时,我们省略了一些细节,这些细节对查询执行性能的影响可能很大。我们没有提到所谓的 “ 推倒 ” 条件。假设我们的 WHERE
条件 P(T1,T2,T3)
可以用一个联合公式表示:
P(T1,T2,T2) = C1(T1) AND C2(T2) AND C3(T3).
在这种情况下,MySQL实际上使用以下嵌套循环算法来执行带有内连接的查询:
FOR each row t1 in T1 such that C1(t1) {
FOR each row t2 in T2 such that P1(t1,t2) AND C2(t2) {
FOR each row t3 in T3 such that P2(t2,t3) AND C3(t3) {
IF P(t1,t2,t3) {
t:=t1||t2||t3; OUTPUT t;
}
}
}
}
你看,每个合取的 C1(T1)
, C2(T2)
, C3(T3)
是最内环的推到最外环的地方进行评估。如果 C1(T1)
是一个非常严格的条件,这个条件下推可能会大大减少从T1
传递给内循环的表的行数 。结果,查询的执行时间可能会大大改善。
对于具有外连接的查询, WHERE
仅在发现外部表中的当前行在内部表中具有匹配项之后才检查条件。因此,从内部嵌套循环中推出条件的优化不能直接应用于具有外部联接的查询。这里我们必须引入条件下推谓词,这些谓词由遇到匹配时打开的标志保护。