哪种MYSQL选择方法?

哪种MYSQL选择方法?,sql,mysql,Sql,Mysql,我有三张桌子 第一->产品 第二->标签 第三->可连接 我想选择所有带有标签的产品。我有两种方法。我想问哪一个更有效 第一种方式->使用while进行两次查询 $query=从产品中选择*; $result=mysql\u query$query while($row = mysql_fetch_array($result, MYSQL_ASSOC)) { $query = "SELECT * FROM connectionTable

我有三张桌子

第一->产品 第二->标签 第三->可连接

我想选择所有带有标签的产品。我有两种方法。我想问哪一个更有效

第一种方式->使用while进行两次查询

$query=从产品中选择*; $result=mysql\u query$query

while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
    $query  = "SELECT * 
                 FROM connectionTable 
           INNER JOIN labels ON labels.labelID = connectionTable.labelID 
                WHERE productID = " . $row['labelID'];
..
..
} 
第二种方式->使用组_CONCAT

大概是这样的:

SELECT GROUP_CONCAT(labelName) 
  FROM connectionTable 
INNER JOIN labels ON labels.labelID = connectionTable.labelID 
INNER JOIN products ON products.productID = connectionTable.productID 
     WHERE productID = " . $row['labelID'] . " GROUP BY productID;

$result=mysql\u query$query

在phpMyAdmin中转储查询并使用EXPLAIN

while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
    $query  = "SELECT * 
                 FROM connectionTable 
           INNER JOIN labels ON labels.labelID = connectionTable.labelID 
                WHERE productID = " . $row['labelID'];
..
..
} 

除此之外,联接总是比嵌套查询快。

这两种方法都不好。在这两种情况下,在循环中都有一个查询。这不是两个串行SQL查询,即一个查询和第二个查询,它们的运行次数与第一个查询中的行数相同


您真正应该做的是将标签和可连接表添加到循环外部的查询中。

您应该考虑进行连接,而不是单独进行两个查询,并解释计划两个查询与连接不会告诉您全部情况

您必须记住,在执行查询时,实际查询之外会发生一些需要时间和资源的事情。验证和解析SQL语句,如果您的MySQL版本支持绑定变量,则可以使用绑定变量在一定程度上缓解该问题,确定检索结果的计划,以及网络时间/流量,尤其是在访问另一台主机上的数据库时。如果您的第一个查询返回一百万行,那么您将执行第二个查询一百万次,并产生网络开销,以便每次都将其与返回的结果集一起发送。这远远低于一次发送联接查询并返回整个数据集并对其进行处理的效率。更不用说在不使用绑定变量的情况下对DB SQL缓存所做的操作了

请注意,效率和响应时间并不相同。从用户的角度来看,效率更高的可能最终会变得更慢。如果用户使用两个单独的查询点击页面,他/她很可能会很快看到结果,因为循环中的各个查询执行并返回可以输出到页面的小返回集。但是,返回所有行所需的时间可能比单个联接要长得多。在单连接的情况下,用户在返回数据之前可能会等待更长的时间,但他们会更快地看到整个数据


我将使用连接,并确保您在productID上连接的列上有索引。根据表大小等,标签id、标签名称上的串联索引可能也会有所帮助,但这需要使用EXPLAIN进行检查以进行验证。查看用户的响应时间,然后从那里开始工作。

第一个版本不是运行2个查询,而是运行1个以上的产品查询。如果 您正在加载所有产品,这很容易:

运行“从产品中选择*”并创建产品地图,以便您可以通过ID访问它们。 运行SELECT*FROM connectionTable JOIN labels ON labels.labelID=connectionTable.labelID,迭代结果,在上一步的映射中查找产品,并将该行添加到产品条目中。
如果只想对有限的一组产品执行此操作,请选择它们,收集产品ID并使用与以前相同的查询,但productID位于何处?、?、?、…

我认为这两种方法中都不使用嵌套查询。在第一个示例中,我有两个串行SQL查询。在第二个查询中,我有一个查询,但是如果表很大,那么连接的一个可能比另一个要花更长的时间吗?您正在为第一个查询中的每个外部结果执行内部sql。除非内部sql异常活跃,否则总是比生成相同结果的联接慢。两者都不是最优的。内部联接效率低下。我不确定它将如何应用于您的情况,但我想说,我需要做的80%的连接都是左连接。当第二个查询可能只返回1个产品时,为什么要将所有产品加载到一个映射中?我们不知道连接表中包含多少ProductID。我希望所有/大多数产品都有一个标签,大多数产品都有不止一个标签。