2009-10-14 84 views
0

我有3张桌子。哪个MYSQL选择方法?

月1日 - >产品 2日 - >标签 3日 - > connectionTable

我要选择与自己的标签,所有的产品。我有两种方法。我想问问哪一个更有效。

1 way->使用而

$查询= “SELECT * FROM产品” 两个查询; $ result = mysql_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']; 
.. 
.. 
} 

###################

第二way->使用GROUP_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_query($ query);

回答

0

在phpMyAdmin中转储您的查询并使用EXPLAIN?

除此之外,JOIN总是比嵌套查询更快。

+0

我想我在两种方法中都不使用嵌套查询。在第一个中,我有两个串行SQL查询。在第二个我有一个查询,但如果表格很大可能会加入一个比其他更长? – UnforgivenX 2009-10-14 17:09:53

+0

您正在执行第一个每个外部结果的内部sql。除非内部的SQL是炽热的,否则总比执行产生相同结果的JOIN慢。两者都不是最佳的。内部连接效率低下。不知道它如何适用于您的情况,但我会说我需要做的连接中有80%是LEFT JOIN的 – 2009-10-14 18:12:14

1

两种方法都不好。在这两种情况下,您都在循环中查询。这不是“两个串行SQL查询”(即查询),而是第二个查询的运行次数与第一个查询中的行数相同。

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

0

你应该看看做JOIN,而不是单独的2个查询,并解释计划2个查询与JOIN'ed不会告诉你整个故事。

你必须记住当你执行一个查询时,在实际查询之外发生的事情需要时间和资源。验证和解析SQL语句(如果您的MySQL版本支持,可以使用绑定变量稍微缓解),确定检索结果的计划以及网络时间/流量,尤其是在访问另一主机上的数据库时。如果您的第一个查询返回了一百万行,那么您将执行第二个查询一百万次,并确定网络开销以便每次发送该查询并返回结果集。这比发送JOIN查询一次并返回整个数据集并处理它要有效得多。更不用说使用绑定变量来处理数据库SQL缓存。

请注意,效率和响应时间并不相同。从用户的角度来看,更有效的方式可能最终会变得更慢。如果用户使用2个单独的查询访问页面,他/她很可能会很快看到结果,因为循环中的单个查询会执行并返回可以输出到页面的小型返回集。尽管返回所有行可能比单个JOIN花费更多的时间。在单个JOIN情况下,用户可能会在返回数据之前等待更长时间,但他们会更快看到整个数据。

我会去加入,并确保你有加入的列(即productID)索引。 label_id,label_name上的连接索引可能也会有帮助,具体取决于表的大小等,但这将是您需要使用EXPLAIN来查看才能验证的内容。看看你的用户的响应时间如何,并从那里开始工作。

0

第一个版本不运行2个查询,它运行1+ number_of_products查询。如果 您加载所有产品,很容易:

  • 运行SELECT * FROM products和创建地图的产品,这样就可以通过ID访问它们。
  • 运行SELECT * FROM connectionTable JOIN labels ON labels.labelID = connectionTable.labelID,迭代结果,从上一步查找映射中的产品,并将该行添加到产品条目中。

如果您只想为有限的产品组执行此操作,请选择它们,收集产品ID并使用与以前相同的查询,但需要WHERE productID IN (?, ?, ?, ...)

+0

为什么在第二个查询只返回1个产品时将所有产品加载到映射中?我们不知道连接表中包含多少个productID。 – 2009-10-14 20:50:16

+0

好吧,我预计所有/大多数产品都有标签,大多数产品都有多个标签。 – 2009-10-15 05:48:34