2

我有一个 PHP 脚本,它遍历一个数组并在每次传递时调用一个 MySQL 存储函数。

它严重影响服务器性能。我认为这对我来说是糟糕的设计。这就是它的工作原理(伪代码)

  1. 从 PHP 中的某个源获取数据
  2. 对于数组中的每一项
    1. 调用 MySQL 存储函数,在表中插入/更新数据
    2. 移至下一项
  3. 结束循环

MySQL 存储函数

  1. 搜索描述性字符串(索引)
  2. 如果存在,则将与其关联的任何 ID 分配给局部变量,否则插入一个新 ID 并将该新 ID 分配给局部变量
  3. 对另一个字符串、ID 对执行上述类似步骤
  4. 插入/更新传递给它的大量数据

试图解决它

  • 最初我有 3 个单独的存储函数,然后我将它们合并为一个。但它并没有解决问题。
  • 我还确保搜索的字段已编入索引
  • 我得出的结论是,它很可能在每次调用时循环并调用存储的函数。也许它分配了一个未释放或在每次后续迭代中缓慢释放的进程/线程
  • 我已经阅读了游标,并且我知道它们不是很好的做法,尤其是对于批量操作,并且几乎总是有一种替代且更有效的非过程(基于集合)的替代方法。还是我应该尝试这条路线?
  • 我还没有尝试在循环中构建整个查询文本,然后将其作为一个大 SQL 批处理运行。虽然我担心超时问题或更难跟踪插入/更新错误。

请分享您的建议和经验。伪代码或片段也将不胜感激提前谢谢!

4

1 回答 1

2

减少查询次数总是好的。在其最基本的形式中,您可以一次插入多行。

// BAD:
while($something) {
    mysql_query("insert into `table` (`fields`) values ('value')");
}
// GOOD:
$rows = [];
while($something) {
    $rows[] = "('value')";
}
if( $rows) mysql_query("insert into `table` (`fields`) values ".implode(",",$rows));

更新有点棘手,但它仍然有效:

// BAD:
while($something) {
    mysql_query("update `table` set `field`='value' where `id`=".$i);
}
// GOOD:
$rows = [];
while($something) {
    $rows[] = "(".$i.",'value')";
}
if( $rows) mysql_query("insert into `table` (`id`,`fields`) values
          ".implode(",",$rows)." on duplicate key update `fields`=values(`fields`)");
                              // ^ this is where the magic happens.

看看您是否可以将这种结构应用到您的查询中,您应该会看到加载时间大大缩短,以获得更快的体验!

于 2013-11-13T21:21:01.033 回答