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

标签 mysql sql join subquery

每个表数据有1万多条记录。列出此数据时哪种查询结果更快。嵌套查询比连接查询更快吗?

嵌套查询:

$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)){

    }
}

哪个结果更快? (我已经对所有表建立了索引)

最佳答案

与大多数事物数据库一样,答案是视情况而定。


首先,请注意,两种查询模式的结果有很大不同。

作为示例,请考虑当 table_3 为空(不包含任何行)时会发生什么情况。使用 JOIN 查询模式,我们不会得到任何结果...结果集将包含零行。

另一个查询对每个表运行单独的查询,返回table_1table_2中的行。

此外,通过 JOIN 模式,我们将从 table_1、table_2...返回数据的冗余副本


但就“更快”而言,通常 JOIN 模式会更快,因为它消除了很多与数据库的往返。发送SQL,解析标记,语义检查,制定执行计划,执行计划,准备结果集,将结果集返回给客户端,等待客户端进行获取,然后清理(关闭语句句柄和丢弃结果集。)

当数据库往返次数急剧增加时,每个语句执行的微小开销开始积累起来。

好处是,对于简单的查询,需要考虑的执行路径数量往往较少,并且我们通常会为每个查询获得一个相当有效的计划(假设有合适的索引可用。


JOIN 模式的风险在于我们可能会生成一个非常大的集合,其中每行都包含大量冗余数据。


让我们考虑一个场景:

如果 table_1 中有 1,000 行。

如果 table_2 中有 1,000 行,而 table_1 中的每一行都有。

如果 table_3 中的每行有 100 行,table_2 中的每一行则为 100 行。

如果 table_4 中的每行有 10 行,table_3 中的每行都有。

如果 table_5 中的每一行对应 table_4 中的 1 行。

这里有一些快速数学计算... 10^3 ^ 10^3 * 10^2 * 10^1 * 10^0 = 10^9

这将导致结果集中有 10 亿行。 table_1 中每行的数据将重复 10^6 次。这是相同 table_1 值的一百万个副本。

我们有可能获得“非常大”的结果集,并且资源需求相应增加,这可能会导致性能损失。

所以我们倾向于采取中间立场。我们更喜欢处理集合而不是处理 RBAR(逐行处理),但我们也希望避免 Hugh Jass 结果集。

最佳性能可能介于这两种方法之间。例如,通过循环处理 table_1 中的各个行,对于检索到的每一行,我们对 JOIN 中的其余四个表运行查询以获取组合结果。

关于mysql - 嵌套查询比连接查询快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50161574/

相关文章:

c# - 您在 mysql 中使用 c# 指定了无效的列序数

mysql - SQL 合并数据并将其转换为列

sql - Oracle SQL : Re-use subquery for CASE WHEN without having to repeat subquery

mysql - 仅显示按特定行分组的所有数据 : Select * from table group by column having column = 'value'

mysql - 在 phpMyadmin 中创建自动增量触发器时出现问题

mysql - 根据列选择最后n条记录

php - 如何在 laravel 中显示发件人消息右侧和接收者消息左侧

linq - Entity Framework - 如何在多个键上使用 OR 条件进行连接

mysql - sql 查询查找可用日期

mysql - 选择多次与映射表匹配的多个项目