一个SQL查询,或循环中的许多查询?

时间:2009-06-03 18:00:35

标签: php sql design-patterns

我需要从表中提取几行并以两种方式处理它们:

  • 在密钥上汇总
  • 逐行排序,按相同的键排序

该表大致如下:

table (
   key,
   string_data,
   numeric_data
)

所以我正在研究我正在写的函数的两种方法。

第一个用一个查询拉取聚合数据,然后在循环内再次查询每组逐行数据(以下是类似PHP的伪代码):

$rows = query(
        "SELECT key,SUM(numeric_data)
         FROM table
         GROUP BY key"
    );

foreach ($rows as $row) {
    <process aggregate data in $row>

    $key = $row['key'];
    $row_by_row_data = handle_individual_rows($key);
}

function handle_individual_rows($key)
{
    $rows = query(
            "SELECT string_data
             FROM table WHERE key=?",
            $key
        );

    <process $rows one row at a time>

    return $processed_data;
}

或者,我可以做一个大问题,让代码完成所有工作:

$rows = query(
    "SELECT key, string_data, numeric_data
     FROM table"
);

foreach ($rows as $row) {
    <process rows individually and calculate aggregates as I go>
}

在此应用中,性能不是实际问题;我只是想编写合理且可维护的代码。

我喜欢第一个选项,因为它更模块化 - 我喜欢第二种选择,因为它看起来结构简单。一种选择比另一种更好还是真的只是风格问题?

8 个答案:

答案 0 :(得分:12)

一次SQL查询。

这将

  • 为数据库
  • 节省大量资金
  • 允许使用更高效的GROUP BY方法

由于数据库可以很好地执行聚合,因此对于可维护性也更好:您将所有结果集逻辑放在一个位置。

以下是返回每一行并计算SUM

的查询示例
SELECT  string_data, numeric_data, SUM(numeric_data) OVER (PARTITION BY key)
FROM    table

请注意,这很可能会使用并行访问来计算不同SUM的{​​{1}},这在key中很难实现。

PHP中的相同查询:

MySQL

答案 1 :(得分:0)

如果表现不是一个问题,我会选择第二个。似乎最微小的一点。

如果表现令人担忧,我的回答是"don't think, profile"。 :)

答案 2 :(得分:0)

第二个答案更清晰,明智和可维护。用更少的代码说同样的事情,这通常更好。

而且我知道你说性能不是一个问题,但为什么要获取的数据超过你的需要?

答案 3 :(得分:0)

我不能从这里的示例中确定,但我想知道是否有机会在SQL查询本身中进行聚合其他处理。在这种情况下,您必须评估“相对于表示SQL代码与PHP代码中的处理的相对舒适度”的“更易维护”。

您是否需要在每一行上执行额外的处理,这会阻止您在SQL查询本身中表达所有内容?

答案 4 :(得分:0)

我认为你不会发现许多情况,因为在循环中进行每次迭代查询是更好的选择。事实上,我认为从不这样做可能是一个很好的经验法则。

换句话说,到数据库的往返次数越少越好。

根据您的数据和实际表,您可以让SQL执行聚合工作,并通过一个查询选择所需的所有行。

答案 5 :(得分:0)

一个SQL查询可能是一个更好的主意。 它避免了你不得不重写关系操作

答案 6 :(得分:0)

我认为你已经回答了自己的问题,因为你说你有两个不同的处理方式:一个聚合和一个一行。

  • 如果你想保持一切可读性和可维护性,在一个查询中混合两者听起来不对,查询将回答两个不同的需求,因此它不会非常易读

  • 即使perf不是问题,在DB服务器上进行聚合比在代码中进行聚合更快

  • 只有一个查询,处理结果的代码会混合两个处理,同时处理行和计算聚合,所以这段时间代码会变得混乱和错误

    < / LI>
  • 相同的代码可能会随着时间的推移而发展,例如逐行可能会变得复杂,并且可能会在聚合部分中产生错误,反之亦然

  • 如果将来你需要拆分这两种处理方法,那么很难解开当时很久以前其他人写过的代码......

除了性能方面的考虑,在可维护性和可读性方面,我建议使用两个查询。

但请记住,性能因素目前可能不是一个问题,但它可以在数据库量增长或其他情况下及时发生,从长远来看,这绝不是一个可以忽略不计的因素......

答案 7 :(得分:0)

即使性能不是问题,你的思想也是如此。当音乐家练习每一个动作都是为了提高音乐家的技巧。作为开发人员,您应该开发每个程序来提高您的技能。迭代循环,虽然数据是草率和丑陋的。 SQL查询很优雅。您想开发更优雅的代码还是更加邋code的代码?