如果您的应用程序代码中有一个记录ID数组,那么从数据库中读取记录的最佳方法是什么?
$idNumsIWant = {2,4,5,7,9,23,56};
显然循环每个ID是不好的,因为你执行 n 查询:
foreach ($idNumsIWant as $memID) {
$DBinfo = mysql_fetch_assoc(mysql_query("SELECT * FROM members WHERE mem_id = '$memID'"));
echo "{$DBinfo['fname']}\n";
}
那么,使用单个查询可能更好吗?
$sqlResult = mysql_query("SELECT * FROM members WHERE mem_id IN (".join(",",$idNumsIWant).")");
while ($DBinfo = mysql_fetch_assoc($sqlResult))
echo "{$DBinfo['fname']}\n";
但是当数组有30,000个元素时,这个方法是否可以扩展?
你如何有效地解决这个问题?
答案 0 :(得分:2)
最好的方法最终取决于您在阵列中拥有的ID数量(显然您不希望向服务器发送50MB SQL查询,即使从技术上讲它可能能够处理它而没有太多麻烦),但主要是关于你将如何处理结果行。
如果ID的数量非常少(假设数千个顶部),使用IN语法的WHERE子句的单个查询将是完美的。您的SQL查询将足够短,以便可靠,高效,快速地传输到数据库服务器。此方法非常适合循环生成记录的单个线程。
如果ID的数量非常大,我建议您将ID数组拆分为多个组,并运行多个查询,每个查询都有一组ID。对于数据库服务器来说可能有点重,但在应用程序端,您可以产生多个线程,并在它们到达时以平行的方式处理多个记录集。
这两种方法都有效。
Cliffnotes:对于这种情况,只要数据提取不是一个很大的瓶颈,就要关注数据的使用。并介绍您的应用程序!
答案 1 :(得分:1)
答案 2 :(得分:1)
当我必须处理这种情况时,我发现至少有三到四种可能的解决方案:
IN()
IN()
中的一个非常大的列表可能不是很好的表现另外,为了便于修改提取逻辑,我会写一个获取id列表的函数,并返回与那些对应的数据列表。
这样,您只需以相同的方式调用此函数,并始终获得相同的数据,而不必担心如何获取该数据;这将允许你在需要时更改提取方法(如果你有一天找到另一种更好的方法),而不会破坏任何东西:函数如何工作将会改变,但是因为它的接口(输入/输出)将保持不变,它将不会为你的其余代码更改一个东西: - )
答案 3 :(得分:1)
如果是我而且我有一个大的in子句值列表,我会使用一个存储过程,其中包含一个包含我想要的值的变量,并使用其中的函数将它们发送到临时表然后加入它。根据要发送的值的大小,您可能需要将其拆分为多个输入视图以进行处理。有没有什么方法可以在数据库中永久存储值(如果他们经常查询)?用户如何选择30,000个值,当然他或她是不是要将它们全部输入?因此,基于join和where子句可能有更好的方法来查询表。
答案 4 :(得分:0)
通过将字符串分成标记来使用StringTokenizer,您可以更轻松地处理此问题,检索多个值的数据