这个问题在这里已经有答案了:
连接与子查询(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)){
}
}
哪个结果更快(我已为所有表编制索引)
1条答案
按热度按时间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中的各行,对于检索到的每一行,我们对联接中的其余四个表运行一个查询,以获得一个组合结果。