我有一个MySQL数据库,在外部提供商上有大约600万个歌曲ID,并且可以通过chrooted访问命令行。
我在大约450记录时得到Bad Gateway错误,即使它一直在更新到记录950.它远离完整的数据库,我真的不知道如何处理它。我也试图限制查询,但正如所说它会停止,手动拆分是不可能的(6000手写!!!)
流程概述如下,伪代码后面有更深入的理解:
提前感谢您的帮助。
伪代码
ini_set('max_execution_time',0);//INFINITE
ini_set("memory_limit", "300M");//MAX SUPPORTED BY HOSTING
$query1 = "SELECT id FROM songs";
$sql = mysqli_query($link, $query1) or die("error");
while ( $row = mysqli_fetch_assoc($sql) ) {
$url = 'https://api.com/tracks?pass='.$pass.'&id='.$row["id"];
$content = file_get_contents($url);
$json = json_decode($content, true);//RETURNS "results" ARRAY
$query2 = "INSERT INTO songs_ok VALUES ";
foreach($json["results"] as $result){
$query2.= "( ";
$query2.= $row["timestamp"].",";
$query2.= $row["artist"].",";
$query2.= " ),";
$query2 = rtrim($query2,", ").";";
$sql2 = mysqli_query($link, $query2) or die("error");
}
}
P.S。我还尝试将INSERT查询置于底部,但显然结果几乎相同。 THX
答案 0 :(得分:1)
这是一个硬编码限制。 直到今天一直工作的解决方法
mysqli_query($link, "set @@session.interactive_timeout = 28800");
mysqli_query($link, "set @@session.wait_timeout = 28800");
答案 1 :(得分:0)
首先:正如@cale_b建议的那样,您应该批量插入,这意味着在单个查询中插入更多记录,例如INSERT INTO table (col1, cols2) VALUES (record1, record1), (record2, record2), (record3, record3), etc...
第二:您应该批量从表中检索数据。意思是,一次检索100行(在sql的SELECT和OFFSET中使用LIMIT完成)。
第一件事将使您的数据库服务器不会过载,第二件事将使您的内存不会超载。
另外,请考虑一些Web服务,例如Cloudflare,将最大执行时间设置为您无法更改的特定时间。然后,您应该将脚本作为控制台应用程序运行,因为在控制台中运行脚本没有最长的执行时间。
您可以使用简单的命令从Web应用程序调用控制台脚本:
$command = 'php /path/to/your_script.php > /dev/null 2>/dev/null &';
shell_exec($command);
添加的> /dev/null 2>/dev/null &
将在一个独立的过程中启动控制台应用程序,因此它无法连接到您的网络应用程序,并且在网络应用程序进程停止时不会中断。