MySQL中的where子句如何工作?

时间:2010-05-11 17:28:53

标签: c++ c mysql

我怀疑。假设R和S分别与属性A和B有2个关系。如果我有查询

Select * 
From R, S
Where R.A = S.B 

这是否像c或c ++中的双For循环一样工作

For( i=0; i<n; i++)
    For( j=0; j<n; j++)
        if (i == j)
           //DO some work 

5 个答案:

答案 0 :(得分:2)

首先:不知道mysql如何在内部优化查询(不知道mysql的内部)。

在纯关系数据库中,这就是你正在做的事情:

SELECT * FROM R, S - &gt;执行交叉连接,生成所有(r,s)元组。

WHERE R.A = S.B - &gt;现在选择那些具有此行为的元组

所以它会遍历所有元组(或多或少像你的代码)。但是,完全有可能mysql会在内部将其减少为一个更有效的内连接,它永远不会创建所有元组,只有R.A=S.B有效的元组。

答案 1 :(得分:2)

是的,至少在概念上。连接创建两个表中元素的笛卡尔交叉,这是您使用两个循环执行的操作,然后Where子句限制条件为true的笛卡尔十字的成员。当然,实现不会实际创建整个笛卡尔十字架;它将使用索引来识别匹配,而无需通过所有成对比较。

答案 2 :(得分:2)

如果这些属性中没有任何索引,那么这正是MySQL必须要做的,而且效率非常低。

尽管如此,拥有索引会让世界变得与众不同。例如,如果S.B上有索引,那么MySQL可以做更多这样的事情:

for (i=0; i<n_r; i++) { // loop over all rows in R
    matching_rows = retrieve_from_index_s_b(i); // very fast operation, like direct array access
    for (j=0; j<matching_rows.length(); j++)
        // do some work 
}

类似地,如果索引在R.A上,那么外部循环将在S中的行上,而内部循环将仅在R中的匹配行上。

如果两个属性都有索引,那么MySQL可以查看每个表中的数据量,并组织循环以便需要最少的工作量。这是MySQL查询优化器的工作,它可以做很多工作来确定查看表的正确顺序,以最小化所需的磁​​盘访问次数。

正如其他人已经提到的那样,SQL主要是一种声明性语言,您可以在其中说出您想要的结果,而无需指定数据库如何获得这些结果。您可以想象数据库总是在执行完整的嵌套循环集,如果这有助于您可视化结果,但只要您正确设置索引,它通常会做更聪明的事情。

答案 3 :(得分:1)

功能方面,是的。这就是它的工作原理。你可以想象它在嵌套for循环中循环遍历两个表中的所有行,并且只选择字段匹配的那些行。

实施方面,情况非常不同。数据库引擎使用多种优化来加速查询。数据库引擎如何实际执行查询取决于许多因素,例如数据库引擎的类型,(非常重要的)索引,数据量等。

答案 4 :(得分:1)

您所描述的是nested loops加入策略。优化器可能会选择此策略或其他连接策略(可用选项将取决于RDBMS here is a summary of some common join algorithms)。

将选择哪个将取决于各种问题,包括JOIN条件(例如,一些仅适用于equijoins),数据是否已经排序,可用内存量,表的大小,索引的可用性等。