- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在我来工作的公司,他们运行一个 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 格式。
谢谢!
2014 年 8 月 28 日更新
所以我想我应该对这个进行更新,以及更长期有效的方法。经过这次讨论,我决定在工作中重建报告生成器。我没有确定的结果数字,但我想我会分享结果是什么。
我认为有点矫枉过正,因为我将整个报告(就返回的数据而言,它非常动态)变成了一个巨大的连接盛宴。大多数联接(如果不是全部)都将值联接到主键,因此它们都运行得非常非常快。如果报告有 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)
并且索引会窒息并死在我的怀里我在它的最后时刻拿着它。所以我所做的是将 ID 以 10 个为一组展开,并运行相同的查询 x/10 次,我的结果比以前更快地获取 way 因为索引喜欢处理 10 个 ID,而不是 500 个,因此,由于执行了 while 语句,我发现我的查询有了很大的改进。
最佳答案
如果正确使用索引,那么使用 JOIN 几乎总是更有效。添加重点是因为最佳效率并不总是等于最佳性能。
不过,实际上并没有一个放之四海而皆准的答案;您应该使用 EXPLAIN
分析查询,以确保确实使用了索引,没有使用不必要的临时表等。在某些情况下,条件共同创建只是不能使用索引的查询。在这些情况下,按照您指定的方式将查询分成几部分可能会更快。
如果我在现有项目中遇到这样的代码,我会质疑它:检查查询,想出不同的方式来执行查询,确保已经考虑了这些事情,为或建立一个科学的、有事实支持的案例反对这种做法。确保原始开发人员尽职调查,因为不使用 JOIN 表面上指向糟糕的数据库或查询设计。不过,最后,结果很明显,如果所有的优化和更正仍然导致连接速度比使用查询片段提供的速度慢,那么更快的解决方案将占上风。对标并根据对标结果采取行动;在软件设计中,没有任何情况表明您应该以糟糕的性能为代价来遵守关于您应该做什么或不应该做什么的任意规则。性能最好的方法就是最好的方法。
关于php - JOINS 与 while 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7390849/
创建一个“海盗对话”,可以选择左手或右手。我希望它对“左”和“右”的不同拼写做出积极的回答(正如您将在代码中看到的那样),但是,当我为所有非“右”或“左”的输入添加最终的“else”代码时,它给了我一
With 语句 对一个对象执行一系列的语句。 With object statements End With 参数 object 必需的部分
While...Wend 语句 当指定的条件为 True 时,执行一系列的语句。 While condition  ; Version [stat
所以我正在处理的代码有一个小问题。 while True: r = input("Line: ") n = r.split() if r == " ":
我有一个对象数组: var contacts = [ { "firstName": "Akira", "lastName": "Laine", "number"
int main() { int f=fun(); ... } int fun() { return 1; return 2; } 在上面的程序中,当从main函数中调用一个
我的项目中有很多 if 语句、嵌套 if 语句和 if-else 语句,我正在考虑将它们更改为 switch 语句。其中一些将具有嵌套的 switch 语句。我知道就编译而言,switch 语句通常更
Rem 语句 包含程序中的解释性注释。 Rem comment 或 ' comment comment 参数是需要包含的注释文本。在 Rem 关键字和 comment 之间应有一个空格。
ReDim 语句 在过程级中声明动态数组变量并分配或重新分配存储空间。 ReDim [Preserve] varname(subscripts) [, varname(subscripts)]
Randomize 语句 初始化随机数生成器。 Randomize [number] number 参数可以是任何有效的数值表达式。 说明 Randomize 使用 number 参数初始
Public 语句 定义公有变量并分配存储空间。在 Class 块中定义私有变量。 Public varname[([subscripts])][, varname[([subscripts])
Sub 语句 声明 Sub 过程的名称、参数以及构成其主体的代码。 [Public [Default]| Private] Sub name [( arglist )]
Set 语句 将对象引用赋给一个variable或property,或者将对象引用与事件关联。 Set objectvar = {objectexpression | New classname
我有这个代码块,有时第一个 if 语句先运行,有时第二个 if 语句先运行。我不确定为什么会这样,因为我认为 javascript 是同步的。 for (let i = 0; i < dataObje
这是一个 javascript 代码,我想把它写成这样:如果此人回答是,则回复“那很酷”,如果此人回答否,则回复“我会让你开心”,如果此人回答的问题包含"is"或“否”,请说“仅键入”是或否,没有任何
这是我的任务,我尝试仅使用简短的 if 语句来完成此任务,我得到的唯一错误是使用“(0.5<=ratio<2 )”,除此之外,构造正确吗? Scanner scn = new Scanner(
有没有办法在 select 语句中使用 if 语句? 我不能在这个中使用 Case 语句。实际上我正在使用 iReport 并且我有一个参数。我想要做的是,如果用户没有输入某个参数,它将选择所有实例。
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: If vs. Switch Speed 我将以 C++ 为例,但我要问的问题不是针对特定语言的。我的意思是一
Property Set 语句 在 Class 块中,声明名称、参数和代码,这些构成了将引用设置到对象的 Property 过程的主体。 [Public | Private] Pro
Property Let 语句 在 Class 块中,声明名称、参数和代码等,它们构成了赋值(设置)的 Property 过程的主体。 [Public | Private] Prop
我是一名优秀的程序员,十分优秀!