SELECT table_1.id, table_2.id FROM table_1 LEFT JOIN table_2 ON table_1.sub_id = table_2.id
当我到达现在的工作岗位时,这就是他们所做的事情。
<?php $query = mysql_query("SELECT sub_id FROM table_1");
while($rs = mysql_fetch_assoc($query)) {
$query_2 = mysql_fetch_assoc(mysql_query("SELECT * FROM table_2 WHERE id = '{$rs['sub_id']}'"));
//blah blah blah more queries
?>
当我问为什么他们用第二种方法时,他们说它比连接查询更快。他们管理着一个拥有数百万条记录的数据库,这些记录存储在不同的表格中,其中一些表格有点宽(按行计算)。他们说,他们希望避免在执行糟糕的查询时使用连接查询,否则会锁定一个或多个表格。还有一件事要记住的是,这个数据库附带了一个庞大的报表生成器,客户可以使用它来构建自己的报表,如果他们构建了一个大的报表,可能会引起一些麻烦。
我很困惑,所以我想向广大程序员公众提出这个问题。做while语句(一次较大的查询以获取许多行,然后进行许多小的子查询)是否比做连接查询(一次拉取较大的查询以获取所有所需数据)更快?只要索引正确,是否重要?还有一件事需要考虑的是,当前DB处于InnoDB格式。
谢谢!
更新于8/28/14
因此,我认为我应该对这个问题进行更新,并分享一下更长时间内的解决方案。在这次讨论之后,我决定在工作中重新构建报表生成器。我没有明确的结果数字,但我想分享一下结果。
我认为我有点过度,因为我将整个报表(返回的数据相当动态)转化为了大量的连接查询。大多数连接查询都将一个值与一个主键进行连接,因此它们非常快。如果报表要拉取30列数据,并且它拉取了2000条记录,那么每个字段都会运行一个查询以获取数据(因为该数据可能在不同的字段上)。 30 x 2000 = 60000,即使在较快的查询时间下,每个查询所需的时间为0.0003秒,总查询时间也为18秒左右(这基本上就是我记得的)。现在,我将查询重建为基于许多主键的大型联接查询,在可能的情况下,相同的报表加载时间约为2-3秒,其中大部分时间用于下载HTML。每个返回的记录根据所需的数据进行0-4次额外的查询(如果可以在连接中获取数据,则75%的时间不需要任何数据)。因此,相同的2000条记录将返回额外的0-8000次查询(比60000好多了)。
我认为while语句在某些情况下很有用,但正如下面评论中所述,基准测试才是关键。在我的情况下,连接操作是更好的选择,但在我的网站的其他领域,while语句更有用。例如,我有一个报告,客户可以请求按多个类别提取数据,并仅返回这些类别的数据。我曾经使用category_id IN(...,...,..,..,等等等)
来处理50-500个ID,但索引会因此而崩溃。所以我将ID分成10组,并运行相同的查询x / 10次,结果比以前快得多,因为索引喜欢处理10个ID,而不是500个,因此我看到了查询的显着改进。