嵌套查询比连接查询快吗?

mznpcxlj  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(819)

这个问题在这里已经有答案了

连接与子查询(19个答案)
两年前关门了。
在每个表数据中有一万多条记录。列出此数据时,什么查询结果更快。嵌套查询比联接查询快吗?
嵌套查询:

$query = $baglanti->prepare("Select * from table_1");
$query->execute();
if($query->rowCount() > 0){
    while($query_data=$query->fetch(PDO::FETCH_ASSOC)){
        $query_2 = $baglanti->prepare("Select * from table_2 where table_1_id = :id");
        $query_2->bindParam(":id", $query_data["id"], PDO::PARAM_INT);
        $query_2->execute();
        if($query_2->rowCount() > 0){
            while($query_2_data=$query_2->fetch(PDO::FETCH_ASSOC)){
                $query_3 = $baglanti->prepare("Select * from table_3 where table_2_id = :id");
                $query_3->bindParam(":id", $query_2_data["id"], PDO::PARAM_INT);
                $query_3->execute();
                if($query_3->rowCount() > 0){
                    while($query_3_data=$query_3->fetch(PDO::FETCH_ASSOC)){
                        table_4
                        table_5
                        ...
                    }
                }
            }
        }
    }
}

内部联接查询:

$query = $baglanti->prepare("Select * from table_1
    INNER join table_2
    on table_1.id=table_2.table_1_id
    INNER join table_3
    on table_2.id=table_3.table_2_id
    INNER join table_4
    on table_3.id=table_4.table_3_id
    INNER join table_5
    on table_4.id=table_5.table_4_id
    ...
    ");
$query->execute();
if($query->rowCount() > 0){
    while($query_data=$query->fetch(PDO::FETCH_ASSOC)){

    }
}

哪个结果更快(我已为所有表编制索引)

ckx4rj1h

ckx4rj1h1#

答案是,和大多数数据库一样,它取决于。
首先,让我们注意到两种查询模式的结果在很大程度上是不同的。
举个例子,考虑一下当 table_3 为空(不包含行)。使用连接查询模式,我们将不会得到任何结果。。。结果集将包含零行。
另一个查询对每个表运行单独的查询,将从中返回行 table_1 以及 table_2 .
另外,使用连接模式,我们将从表1、表2返回数据的冗余副本。。。
但就“更快”而言,连接模式通常会更快,因为它消除了大量到数据库的往返。发送sql、解析令牌、语义检查、制定执行计划、执行计划、准备结果集、将结果集返回给客户端、等待客户端执行提取,然后进行清理(关闭语句句柄并丢弃结果集)
当数据库往返次数急剧增加时,每个语句执行的小开销开始显著增加。
好处是,对于一个简单的查询,需要考虑的执行路径的数量往往较少,而且我们通常可以通过每个查询得到一个合理有效的计划(假设有合适的索引可用)。
连接模式的风险在于,我们可以生成一个非常大的集合,其中每行都包含大量冗余数据。
让我们考虑一个场景:
如果表1有1000行。
如果我们在表2中有1000行,那么表1中的每一行对应1000行。
如果我们在表3中有100行,那么表2中的每一行对应100行。
如果表4中有10行,那么表3中的每一行对应10行。
如果我们在表5中有一行对应表4中的每一行。
一些简单的数学。。。10^3 ^ 10^3 * 10^2 * 10^1 * 10^0 = 10^9
这将在resultset中产生10亿行。表1中每行的数据将重复10^6次。也就是一百万份相同的表1的值。
我们可能会有一个“非常大”的结果集,并相应地增加资源需求,这可能会导致性能损失。
所以我们倾向于中间立场。我们更喜欢处理集合而不是处理rbar(逐行处理),但是我们也希望避免hugh jass resultsets。
最佳性能可能会在这两种方法之间获得。例如,通过在循环中处理表1中的各行,对于检索到的每一行,我们对联接中的其余四个表运行一个查询,以获得一个组合结果。

相关问题