SQL语句中的计算速度

时间:2011-06-21 20:18:26

标签: php mysql performance

我有一个包含三个字段的数据库(MySQL)表:id,score和percent。

长话短说,我需要对每个看起来像这样的记录进行计算:

(得分* 10)/(1 - %)=值

然后我需要在我的代码和ORDER BY字段中使用该值。编写SQL不是我的问题 - 我只是担心这个语句的效率。在我的SQL语句中进行计算是最有效的资源使用,还是我最好抓住数据然后通过PHP进行数学运算?

如果SQL是最好的方法,那么我是否可以记住哪些提示尽可能快地保持我的SQL拉?

更新1:只是为了澄清一些问题,因为似乎许多答案都有不同的看法:得分和百分比都会不断变化。实际上,几乎每次用户与应用程序交互时,这些字段都会发生变化(这些字段实际上链接到用户,顺便说一句)。

就记录数而言,现在它非常小,但我希望扩展到大约200万条记录(用户)的目标集。在任何给定的时间我只需要20条记录,但我需要它们是按此计算值排序的前20条记录。

5 个答案:

答案 0 :(得分:4)

听起来这个计算值在您的业务领域具有固有意义;如果是这种情况,我会计算一次(例如在创建记录时),并像使用任何普通字段一样使用它。这是迄今为止实现您想要的最有效的方式 - 插入或更新的额外计算对性能影响最小,从那时起您不必担心谁在哪里进行计算。 缺点是您必须更新“插入”和“更新”逻辑才能执行此计算。我通常不喜欢触发器 - 它们可能是不可穿透的错误的来源 - 但这是我考虑它们的情况(http://dev.mysql.com/doc/refman/5.0/en/triggers.html )。

如果由于某种原因你不能这样做,我建议你在数据库服务器上这样做。这应该是非常活泼的,除非你正在处理大量的记录;在这种情况下,“order by”将是一个真正的性能问题。如果你在PHP端执行相同的逻辑,这将是一个更大的性能问题 - 但是从性能的角度来看,你的数据库往往是瓶颈,因此影响更大。 如果你正在处理大量的记录,你可能只需要咬紧牙关并继续我的第一个建议。

如果不需要按计算排序,你也可以在PHP端执行此操作;然而,在PHP中对数组进行排序并不是我想要对大型结果集进行的操作,而且在数据库中进行排序似乎很浪费(这样做很擅长)。

所以,毕竟,我的实际建议归结为:

  • 做最简单的事情
  • 在你的约束下测试它是否足够快 项目
  • 如果没有,迭代重构更快的解决方案,重新测试
  • 一旦你达到“足够好”,继续前进。

基于编辑1

我已经回答了你自己的问题,我认为 - 向PHP返回(最终)200万行,只是为了找到前20个记录(在逐个计算它们的“值”之后)将会非常慢。所以在PHP中计算实际上不是一种选择。

所以,你将在服务器上计算它。我的建议是创建一个具有SQL来执行计算的视图(http://dev.mysql.com/doc/refman/5.0/en/create-view.html);使用200,200K和2M记录对视图的性能进行基准测试,看看它是否足够快。

如果在2M用户/记录上不够快,您可以随时创建一个常规表,在“值”列上添加索引,并且在客户端代码中需要更改的内容相对较少;你可以通过触发器填充新表,客户端代码可能永远不知道发生了什么。

答案 1 :(得分:1)

数据库中进行数学运算会更有效,因为无论客户端有多快和速度有多慢,从数据库到客户端来回传输数据都会比简单表达式慢一些数据库是。

答案 2 :(得分:0)

测试一下,让我们知道性能结果。我认为这将取决于结果集中的数据量。对于SQL位,只需确保where子句具有覆盖索引。

答案 3 :(得分:0)

你在哪里做数学不应该太重要。无论哪种方式都是相同的基本操作。现在,如果MySQL运行在与PHP代码不同的服务器上,那么您可能会关心哪个CPU进行计算。您可能希望SQL服务器执行更多“艰苦工作”,或者您可能希望让SQL服务器执行“仅SQL”,并将数学逻辑移动到PHP。

另一个考虑因素可能是带宽使用(如果MySQL没有与PHP在同一台机器上运行) - 你可能希望让MySQL返回哪个更短的形式,以减少网络带宽。

如果它们都在同一个物理硬件上,那么从纯粹的CPU使用角度来看,它可能没有明显区别。

我提供的一个提示是对原始值(百分比)而不是计算值执行ORDER BY - 这样MySQL可以使用百分比列上的索引 - 它不能使用计算的索引值。

答案 4 :(得分:0)

如果您的记录数量越来越多,您的脚本(及其内存)将比mysql更快地达到其极限。你打算取得所有记录吗? Mysql一般会更快。 我不知道如何在ORDER BY之后使用php中计算的值。如果你打算在php中进行排序,它会变得更慢,但这完全取决于你正在处理的记录数量。