我有一个.txt
文件,其中包含60,000个英文单词列表。我想将它们插入到我的数据库中,所以我只是按照这里的说明进行操作。
$file = new SplFileObject('list.txt');
foreach ($file as $line => $word) {
$p = new PDO('mysql:host=localhost; dbname=test_dictionary', 'root', 'test');
$p->query("INSERT INTO words (english) VALUES('$word') ");
}
现在,在我运行此脚本后,我收到以下错误:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [1040] Too many connections' in /var/www/skillz/test/curl/index.php:17 Stack trace: #0 /var/www/test/index.php(17): PDO->__construct('mysql:host=loca...', 'root', 'test') #1 {main} thrown in /var/www/test/index.php on line 4
line 4
位于new PDO('mysql:')
所在的位置。所以,我试图搜索此错误,并找到了this answer that seemed a solution。我相应地编辑了mysql,如
$ vi /etc/my.cnf
max_connections=250
但是我仍然得到同样的错误,我在CentOS 6.5中运行PHP-FPM,NGINX MySql 5.5.38
答案 0 :(得分:2)
不要为每个单词打开一个新的连接。您只需要在插入的生命周期内打开一个连接。我不确定PDO对象的真实生命周期,我知道当它们不被使用时它们会被清理干净,但是垃圾收集可能在几分钟内没有这样做,并且对于60,000单词,你可以更快地达到数据库连接的限制,而不是清理它们。
$file = new SplFileObject('list.txt');
$p = new PDO('mysql:host=localhost; dbname=test_dictionary', 'root', 'test');
foreach ($file as $line => $word) {
$p->query("INSERT INTO words (english) VALUES('$word') ");
}
答案 1 :(得分:2)
您应该在foreach之外声明SQL连接。 因为它会产生60.000个连接。
$file = new SplFileObject('list.txt');
$p = new PDO('mysql:host=localhost; dbname=test_dictionary', 'root', 'test');
foreach ($file as $line => $word) {
$p->query("INSERT INTO words (english) VALUES('$word') ");
}
您只需要声明SQL连接一次,就可以随时使用它。 如果你把它放在foreach中,那么每个单词都会建立一个SQL连接,这就是你收到该消息的原因。
答案 2 :(得分:2)
解决方案1 使用批处理插入语句:
INSERT INTO words (col1, col2) VALUES ('val1', 'val2'), ('val3', 'val4'), ...('val3n', 'val4n');
如果您还想检查某些行是否失败,则会失败。所以,下面是另一种解决方案。
解决方案2
创建持久数据库连接。这将在循环的所有迭代中使用相同的连接。
$file = new SplFileObject('list.txt');
$p = new PDO('mysql:host=localhost; dbname=test_dictionary', 'root', 'test', array(
PDO::ATTR_PERSISTENT => true)); //Persistent Database Connection
foreach ($file as $line => $word) {
$p->query("INSERT INTO words (english) VALUES('$word') ");
}
$p = null; //Destroy Connection