每个表数据有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_1
和table_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/