我正致力于提高Web应用程序的数据导入性能,并且有一项大幅提升性能的事情是将数据库相关逻辑从服务器端代码移植到数据库中的存储过程和函数中。
此外,在处理大量类似的查询时,将它们分批排队以便稍后在单个SQL事务中执行,从而明显减少导入过程的瓶颈。
不幸的是,我遇到了一个问题,由于某种原因,我不能在一个SQL命令中多次调用存储过程。
使用此SQL,我连续两次调用LegacyUpdateProduct
来展示我的问题。
SQL
存储过程接受带有数据的一些参数,不返回结果集,而out给出带有行ID的@ID
变量,在这种情况下我们不需要。
CALL LegacyUpdateProduct(92,'00010','ADAISD 345',18.81,'91020200','FSB92','GS8219','FSB92',TRUE,2,3,0,0,@ID);CALL LegacyUpdateProduct(277,'0002335600','TPASD 987',6.04,'0 002 335 ','UX79','','',TRUE,2,3,0,0,@ID);
PHP
在PHP中,任何人都希望只使用对LegacyUpdateProduct
的两次调用来运行查询,并且一切都会正常。
$sql = "CALL LegacyUpdateProduct(92,'00010','ADAISD 345',18.81,'91020200','FSB92','GS8219','FSB92',TRUE,2,3,0,0,@ID);CALL LegacyUpdateProduct(277,'0002335600','TPASD 987',6.04,'0 002 335 ','UX79','','',TRUE,2,3,0,0,@ID);"
# With Code Igniter
$this->db->query($sql);
# Or with raw PHP
mysqli_query($this->db->conn_id, $sql);
可悲的是,情况并非如此。使用Code Igniter或使用普通PHP运行此查询会引发SQL错误。
注意:我使用细齿梳子检查数据,并使用Code Igniter DB转义机制生成更安全的查询。
错误号:1064您的SQL语法错误
最有趣的是,当我在PHPMyAdmin或MySQL Workbench中复制并粘贴所谓的错误SQL时,它运行顺畅,没有错误或警告。
实际上,我在单个查询中连续多达50次调用LegacyUpdateProduct
,而PHPMyAdmin和MySQL Workbench没有问题。
我已经浏览了Google和SO,看了一些可能相关或有帮助的问题,但是还没有发现很多事情,除了这可能是某些类型的Code Igniter错误,但即使是普通的PHP我发现了同样的问题。
在对另一个有点相关的SO question的回答中,它提到这可能是Code Igniter错误,但是它没有解释为什么使用普通的PHP mysqli_query()
这个查询失败。
在另一个question的注释中,对于另一个错误,暗示可能存在并发问题,在不等待前一个完成的情况下,无法对该过程进行顺序调用。我没有足够的理解MySQL并发来声明,但是,不应该在查询之后执行查询中的每个命令。
帮助?
答案 0 :(得分:0)
在PHP中,任何人都希望只使用两次调用
运行查询
没有像“两次调用的查询”这样的事情。你实际拥有的是两个SQL查询。虽然mysqli :: query每次调用只能运行一个SQL查询。
在处理大量类似的查询时,将它们分批排队,以便稍后在单个SQL命令中执行,导致导入过程的瓶颈明显减少。
最有可能是famous innodb's paranoid mode。将其关闭或将更新包装在事务中。并且您将看到单独的query()调用没有明显减少。