在我上类的公司中,他们运行一个PHP/MySQL关系数据库。我一直以为,如果我需要从不同的表中提取不同的信息,那我可以做一个简单的连接来提取诸如...的数据。
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语句(如果需要的话,可以执行一个较大的查询以拉很多行,然后进行很多小小的子查询)或执行联接(拉动)是否真的更快?一次较大的查询以获取所需的所有数据)。只要索引正确完成,这有关系吗?要考虑的另一件事是当前数据库为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语句更为有用。在一个实例中,我有一个报告,其中客户可以请求多个类别进行分类,并且仅返回这些类别的数据。发生了什么事,我有一个带有50-500个ID的
category_id IN(...,...,..,.., etc etc etc)
,当我在最后关头握住索引时,索引会cho住并死在我的怀里。因此,我所做的工作是将ID分成10个组,并执行相同的查询x/10次,因此我的结果获取速度比以前快了,因为索引喜欢处理10个ID,而不是500个,所以我看到了一个很大的改进我的查询然后由于执行while语句。 最佳答案
如果正确使用了索引,那么使用JOIN几乎总是更有效率。添加重点是因为最佳效率并不总是等于最佳性能。
但是,实际上并没有一个“千篇一律”的答案。您应该使用EXPLAIN
分析查询,以确保确实使用了索引,没有不必要的临时表使用,等等。在某些情况下,条件共同导致创建仅不能使用索引的查询。在这种情况下,按照您指定的方式将查询分成几部分可能会更快。
如果我在现有项目中遇到过这样的代码,我会提出以下问题:检查查询,考虑执行查询的不同方法,确保已考虑了这些问题,建立了科学的,事实支持的支持或反对实践的案例。 。确保不对原始开发人员进行尽职调查,因为未使用JOIN会表面上指出不良的数据库或查询设计。但是,最后,结果大声疾呼,如果所有优化和更正仍然导致联接比使用查询片段提供的联接慢,则以更快的解决方案为准。进行基准测试并根据基准测试结果采取行动;在软件设计中,绝不应该为了降低性能而牺牲对应做或不应该做的任意规则的遵守。最佳方法是最佳方法。