我需要从表中提取几行并以两种方式处理它们:
该表大致如下:
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>
}
在此应用中,性能不是实际问题;我只是想编写合理且可维护的代码。
我喜欢第一个选项,因为它更模块化 - 我喜欢第二种选择,因为它看起来结构简单。一种选择比另一种更好还是真的只是风格问题?
答案 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的代码?