嵌套的 Foreach 循环花费了太多时间
Posted
技术标签:
【中文标题】嵌套的 Foreach 循环花费了太多时间【英文标题】:Nested Foreach loop taking too much time 【发布时间】:2016-12-08 18:33:21 【问题描述】:我正在使用嵌套 Foreach 循环将数据存储在 mysql 中。但它需要太多的处理时间。如何减少最大执行时间。
foreach ($results as $r)
mysqli_query($con,"insert into commercial values('".mysqli_real_escape_string($con,$r['MST_MLS_NUMBER'])."')");
$val=1;
$objects = $rets->GetObject('Property', 'Photo', $r['MST_MLS_NUMBER'], '*', 0);
foreach ($objects as $pho)
mysqli_query($con,"insert into cmtval values('".mysqli_real_escape_string($con,$r['MST_MLS_NUMBER'])."')");
【问题讨论】:
$r['MST_MLS_NUMBER']
和 $pho['MST_MLS_NUMBER']
在单个循环中是不同的值吗?
在单循环内的一次处理中没有类似的值。我已经编辑了问题。
@Anant 实际上我正在使用该库来存储 MLS 数据。采用嵌套循环的原因是我需要在插入记录时存储与相同 mls 编号相关的图像。库中的图像对象调用不同。
【参考方案1】:
你应该使用bulk insert
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
通过 foreach 循环,您应该首先执行查询,然后使用 mysqli_query
执行查询。
$query1 = "insert into commercial values ";
$query2 = "insert into cmtval values ";
foreach ($results as $r)
$query1 .= "('" . mysqli_real_escape_string( $con, $r['MST_MLS_NUMBER']) . "'), ";
$val=1;
$objects = $rets->GetObject('Property', 'Photo', $r['MST_MLS_NUMBER'], '*', 0);
foreach ($objects as $pho)
$query2 .= "('" . mysqli_real_escape_string( $con, $r['MST_MLS_NUMBER']) . "'), ";
mysqli_query($con, $query1);
mysqli_query($con, $query2);
我没有测试过代码。测试并让我知道是否缺少任何东西。 批量更新减少了一些时间。
此外,如果您在单个查询中在 DB 中保存了太多数据,并且如果您有太多索引,则插入数据需要时间。
【讨论】:
这比我上面的要好得多。但是@somnath 也需要时间。可能是因为我将 base64 编码的图像数据存储为同一查询中的 BLOB 类型。? 这就是为什么它需要时间。因为 base64 编码的图像在单个元组中占用大约 39000 个单词。 @junkkrr 另见quora.com/Why-would-an-INSERT-query-be-slow-in-MySQL 和***.com/questions/9722603/… 好的,兄弟。感谢您的帮助。 :-)【参考方案2】:你可以做这样的事情
foreach ($results as $r)
mysqli_query($con,"insert into commercial values('".mysqli_real_escape_string($con,$r['MST_MLS_NUMBER'])."')");
$val=1;
$objects = $rets->GetObject('Property', 'Photo', $r['MST_MLS_NUMBER'], '*', 0);
// generate partial query strings for insert multiple records
$numbers=array();
foreach ($objects as $pho)
$numbers[]= "('".mysqli_real_escape_string($con,$pho['MST_MLS_NUMBER'])."')";
mysqli_query($con,"insert into cmtval values".implode(",",$numbers)); // it will insert multiple record
【讨论】:
【参考方案3】:您可以使用准备语句并使用要插入的不同值执行
例如
// prepare and bind
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);
// set parameters and execute
$firstname = "John";
$lastname = "Doe";
$email = "john@example.com";
$stmt->execute();
$firstname = "Mary";
$lastname = "Moe";
$email = "mary@example.com";
$stmt->execute();
$firstname = "Julie";
$lastname = "Dooley";
$email = "julie@example.com";
$stmt->execute();
设置参数和执行行应该在你的 foreach 循环中。
准备好的语句和绑定的参数 准备好的语句是一种用于高效重复执行相同(或相似)SQL语句的功能。
准备好的语句基本上是这样工作的:
准备:创建一个 SQL 语句模板并将其发送到 数据库。某些值未指定,称为参数 (标记为“?”)。示例:INSERT INTO MyGuests VALUES(?, ?, ?) 数据库对 SQL 进行解析、编译和查询优化 语句模板,并存储结果而不执行它 执行:稍后,应用程序将值绑定到 参数,然后数据库执行该语句。应用程序 可以根据需要使用不同的语句多次执行该语句 价值观
【讨论】:
以上是关于嵌套的 Foreach 循环花费了太多时间的主要内容,如果未能解决你的问题,请参考以下文章